Xamarin Forms - Usando SQLite com MVVM - II

 Neste artigo vou mostrar como o SQLite em uma aplicação Xamarin Forms usando o padrão MVVM.

Continuando a primeira parte do artigo vamos definir as Views e as ViewsModels do projeto.

Antes de criar as views e views models precisamos registrar os serviços criados usando o DependencyService para poder usar o recurso da injeção de dependência do Xamarin.

O DependencyService permite que aplicativos chamem a funcionalidade específica da plataforma de código compartilhado. Essa funcionalidade permite que os aplicativos xamarin. Forms realizem qualquer tarefa que um aplicativo nativo pode fazer.

Assim, o DependencyService é um resolvedor de dependência. Na prática, definimos uma e o DependencyService localiza a implementação correta da interface de vários projetos de plataforma.

Vamos abrir o arquivo App.xaml.cs e incluir o código a seguir:

using PedidoApp.Services;
using PedidoApp.Views;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
namespace PedidoApp
{
   public partial class App : Application
   {
       IPedidoRepository _pedidoRepository;
       public App ()
       {
           InitializeComponent();
       //aplica a injeção de dependência nos serviços implementados
       DependencyService.Register<IMessageService, MessageService>();
       DependencyService.Register<INavigationService, NavigationService>();
       //cria uma instância do repositorio
       _pedidoRepository = new PedidoRepository();
        //invoca o evento 
        OnAppStart();
     }
     private void OnAppStart()
     {
            //obtem todos os dados 
            var getLocalDB = _pedidoRepository.GetAllPedidosData();
            //se existir dados então exibe a lista senão inclui dados
            if (getLocalDB.Count > 0)
            {
                MainPage = new NavigationPage(new PedidoLista());
            }
            else
            {
                MainPage = new NavigationPage(new AddPedido());
            }
        }
        protected override void OnStart ()
        {
	// Handle when your app starts
        }
        protected override void OnSleep ()
        {
           // Handle when your app sleeps
        }
         protected override void OnResume ()
         {
	 // Handle when your app resumes
         }
     }
}

No código registramos os serviços para mensagens e navegação e já acessamos o repositório para exibir a lista de pedidos, se houver pedidos ou exibir a página para incluir um novo pedido.

Definindo as Views e Views Models

Todas as views serão criadas na pasta Views e as Views Models na pasta ViewModels. (Com exceção da view App.xaml que esta na raiz do projeto)

Vou iniciar apresentando o código da View Model BasePedidoViewModel que será herdada pelas demais views models:

using FluentValidation;
using PedidoApp.Models;
using PedidoApp.Services;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Xamarin.Forms;
namespace PedidoApp.ViewModels
{
    public class BasePedidoViewModel : INotifyPropertyChanged
    {
        public Pedido _pedido;
        public IValidator _pedidoValidator;
        public IPedidoRepository _pedidoRepository;
        protected IMessageService _messageService;
        protected INavigationService _navigationService;
        public BasePedidoViewModel()
        {
            _messageService = DependencyService.Get<IMessageService>();
            _navigationService = DependencyService.Get<INavigationService>();
        }
        public string Titulo
        {
            get => _pedido.Titulo;
            set
            {
                _pedido.Titulo = value;
                NotifyPropertyChanged(nameof(Titulo));
            }
        }
        public string Link
        {
            get => _pedido.Link;
            set
            {
                _pedido.Link = value;
                NotifyPropertyChanged(nameof(Link));
            }
        }
        public decimal Preco
        {
            get => _pedido.Preco;
            set
            {
                _pedido.Preco = value;
                NotifyPropertyChanged(nameof(Preco));
            }
        }
        public string Descricao
        {
            get => _pedido.Descricao;
            set
            {
                _pedido.Descricao = value;
                NotifyPropertyChanged(nameof(Descricao));
            }
        }
        List<Pedido> _pedidoLista;
        public List<Pedido> PedidoLista
        {
            get => _pedidoLista;
            set
            {
                _pedidoLista = value;
                NotifyPropertyChanged(nameof(PedidoLista));
            }
        }
        #region INotifyPropertyChanged      
        public event PropertyChangedEventHandler PropertyChanged;
        protected void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion
    }
}

A seguir temos o código da ContentView PedidoView, que será criada na pasta Views, e que será herdada pelas Views DetailsPage e AddPedido usadas na aplicação :

Agora vou apresentar o código usado na implementação das Views no arquivo XAML, no code-behind e depois da respectiva ViewModel.

A view PedidoLista.xaml

O code-behind PedidoLista.xaml.cs

A view model PedidoListaViewModel que herda de BasePedidoViewModel:

using PedidoApp.Models;
using PedidoApp.Services;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
namespace PedidoApp.ViewModels
{
    public class PedidoListaViewModel : BasePedidoViewModel
    {
        public ICommand AddCommand { get; private set; }
        public ICommand DeleteAllPedidosCommand { get; private set; }
        public PedidoListaViewModel()
        {
            _pedidoRepository = new PedidoRepository();
            AddCommand = new Command(async () => await ExibirAddPedido());
            DeleteAllPedidosCommand = new Command(async () => await DeleteAllPedidos());
            EncontrarPedidos();
        }
        void EncontrarPedidos()
        {
            PedidoLista = _pedidoRepository.GetAllPedidosData();
        }
        async Task ExibirAddPedido()
        {
            await _navigationService.NavigateToAddPedido();
        }
        async Task DeleteAllPedidos()
        {
            bool respostaUsuario = await _messageService.ShowAsyncBool("Lista de Pedidos", 
"Deletar todos os detalhes de pedidos ?", "OK", "Cancelar");
            if (respostaUsuario)
            {
                _pedidoRepository.DeleteAllPedidos();
                await _navigationService.NavigateToAddPedido();
            }
        }
        async void ExibirPedidoDetails(int selectedPedidoID)
        {
            await _navigationService.NavigateToDetailsPage(selectedPedidoID);
        }
        Pedido _selectedPedidoItem;
        public Pedido SelectedPedidoItem
        {
            get => _selectedPedidoItem;
            set
            {
                if (value != null)
                {
                    _selectedPedidoItem = value;
                    NotifyPropertyChanged("SelectedPedidoItem");
                    ExibirPedidoDetails(value.Id);
                }
            }
        }
    }
}

A view AddPedido.xaml - Esta view herda da view PedidoView :

l

O code-behind AddPedido.xaml.cs :

A view model AddPedidoViewModel.cs  que herda de BasePedidoViewModel:

using PedidoApp.Models;
using PedidoApp.Services;
using PedidoApp.Validator;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
namespace PedidoApp.ViewModels
{
    public class AddPedidoViewModel : BasePedidoViewModel
    {
        public ICommand AddPedidoCommand { get; private set; }
        public ICommand ViewAllPedidosCommand { get; private set; }
        public AddPedidoViewModel()
        {
            _pedidoValidator = new PedidoValidator();
            _pedido = new Pedido();
            _pedidoRepository = new PedidoRepository();
            AddPedidoCommand = new Command(async () => await AddPedido());
            ViewAllPedidosCommand = new Command(async () => await ExibirPedidoLista());
        }
        async Task AddPedido()
        {
            var resultadoValidacao = _pedidoValidator.Validate(_pedido);
            if (resultadoValidacao.IsValid)
            {
                bool respostaUsuario = await _messageService.ShowAsyncBool("Adicionar Pedido",
"Deseja salvar os detalhes do pedido?", "OK", "Cancela");
                if (respostaUsuario)
                {
                    _pedidoRepository.InsertPedido(_pedido);
                    await _navigationService.NavigateToPedidoLista();
                }
            }
            else
            {
                await _messageService.ShowAsync("Adicionar Pedido", resultadoValidacao
.Errors[0].ErrorMessage, "OK");
            }
        }
        async Task ExibirPedidoLista()
        {
            await _navigationService.NavigateToPedidoLista();
        }
        public bool IsViewAll => _pedidoRepository.GetAllPedidosData().Count > 0 ? true : false;
    }
}

A view DetailsPage.xaml que herda de PedidoView :

O code-behind de DetailsPage.xaml.cs :

A view model DetailsViewModel que herda de BasePedidoViewModel :

using PedidoApp.Models;
using PedidoApp.Services;
using PedidoApp.Validator;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
namespace PedidoApp.ViewModels
{
    public class DetailsViewModel : BasePedidoViewModel
    {
        public ICommand UpdatePedidoCommand { get; private set; }
        public ICommand DeletePedidoCommand { get; private set; }
        public DetailsViewModel(int selectedPedidoID)
        {
            _pedidoValidator = new PedidoValidator();
            _pedido = new Pedido();
            _pedido.Id = selectedPedidoID;
            _pedidoRepository = new PedidoRepository();
            UpdatePedidoCommand = new Command(async () => await UpdatePedido());
            DeletePedidoCommand = new Command(async () => await DeletePedido());
            EncontrarDetalhesDoPedido();
        }
        void EncontrarDetalhesDoPedido()
        {
            _pedido = _pedidoRepository.GetPedidoData(_pedido.Id);
        }
        async Task UpdatePedido()
        {
            var resultadoValidacao = _pedidoValidator.Validate(_pedido);
            if (resultadoValidacao.IsValid)
            {
                bool isUserAccept = await _messageService.ShowAsyncBool("Detalhes do Pedido", 
"Atualiza detalhes do Pedido ?", "OK", "Cancelar");
                if (isUserAccept)
                {
                    _pedidoRepository.UpdatePedido(_pedido);
                    _navigationService.PopAsyncService();
                }
            }
            else
            {
                await _messageService.ShowAsync("Detalhes do Pedido", resultadoValidacao
.Errors[0].ErrorMessage, "OK");
            }
        }
        async Task DeletePedido()
        {
            bool respostaUsuario = await _messageService.ShowAsyncBool("Detalhes do Pedido",
 "Deletar detalhes do pedido", "OK", "Cancelar");
            if (respostaUsuario)
            {
                _pedidoRepository.DeletePedido(_pedido.Id);
                _navigationService.PopAsyncService();
            }
        }
    }
}

Seguindo as orientações e implementando o código mostrado nos artigos, sua aplicação Xamarin Forms estará usando o SQLite de forma aderente ás boas práticas e esta usando o padrão MVVM de forma correta.

O código completo do projeto esta no Curso de Xamarin Forms.

"Ora, àquele que é poderoso para vos guardar de tropeçar, e apresentar-vos irrepreensíveis, com alegria, perante a sua glória,
Ao único Deus sábio, Salvador nosso, seja glória e majestade, domínio e poder, agora, e para todo o sempre. Amém."

Judas 1:24,25

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

  Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter

Referências:


José Carlos Macoratti