Xamarin Forms - Usando o Realm Mobile Database localmente - III


Neste artigo vou mostrar como usar o banco de dados Realm para realizar a persistência de informações localmente em uma aplicação Xamarin Forms usando os no Visual Studio 2017 e a linguagem C#.

Continuando a série de artigos sobre o Realm vamos agora usar o Realm em outra aplicação Xamarin Forms.

Recursos usados:

Criando o projeto no Visual Studio 2017 Community e definindo a página principal

Abra o Visual Studio Community 2017 e clique em New Project;

Selecione Visual C#, o template Cross Plataform e a seguir Cross Plataform App(Xamarin.Forms or Native);

Informe o nome XF_RealmDB2 e clique no botão OK;

A seguir selecione Blank App e marque as opções - Xamarin.Forms e Portable Class Library (PCL) e clique em OK;

Será criado um projeto contendo no projeto Portable as páginas App.xaml e MainPage.xaml.

No code-behind do arquivo App.xaml temos a classe App.cs que irá conter o código compartilhado e que vamos usar neste artigo.

No arquivo App.cs inclua o código a seguir onde definimos a página principal da aplicação como sendo a página MainPage:

using Xamarin.Forms;
namespace XF_RealmDB
{
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();
            MainPage = new NavigationPage(new XF_RealmDB.MainPage());
        }
        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
        }
    }
}

Ao final teremos as referências incluídas em todos os projetos da nossa solução. Iremos usar a página MainPage.xaml como página principal da nossa aplicação.

Incluindo pacote Realm Mobile Database no projeto

Agora vamos incluir uma referência ao pacote do Realm Mobile DataBase via Nuget.

No menu Tools clique em Nuget Package Manager -> Manage Nuget Packages for Solution e selecione o pacote Realm:

Selecione todos os projetos e clique no botão Install. Além do pacote Realm, também serão instaladas as dependências Realm.DataBase e Realm.DataBinding.

Definindo o modelo de domínio da aplicação : A classe Carro

Vamos criar uma aplicação para gerenciar informações de carros, logo vamos definir uma classe chamada Carro que será o nosso modelo de domínio.

Crie uma pasta Model no projeto (Project-> New Folder) e a seguir crie a classe Carro.cs conforme mostra o código abaixo:

using Realms;
namespace XF_RealmDB.Model
{
    public class Carro : RealmObject
    {
        public string Marca { get; set; }
        public string Modelo { get; set; }
        public string Imagem { get; set; }
    }
}

No código estamos usando o namespace : using Realms para que a classe possa herdar de RealmObject.

Os modelos de dados definindos usando o Realm usam classes C# tradicionais com propriedades. Basta herdar de RealmObject a classe base para criar os objetos do modelo de dados que podem ser persistido no Realm. A principail restrição é que você só pode usar um objeto na thread na qual ele foi criado, ou seja, você não pode passar o objeto para outra thread.

Definindo o código a página principal : MainPage

Agora vamos definir o código XAML da página MainPage :

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:XF_RealmDB2"
             xmlns:converters="clr-namespace:XF_RealmDB2.ValueConverters"
             x:Class="XF_RealmDB2.MainPage"
             Title="Marcas Famosas">
    <ContentPage.Resources>
        <ResourceDictionary>
            <converters:StringToImagemConverter x:Key="stringToImagemConverter"></converters:StringToImagemConverter>
        </ResourceDictionary>
    </ContentPage.Resources>
    <ListView ItemsSource="{Binding CarrosCollection}" Margin="24" HasUnevenRows="true" ItemSelected="ListView_ItemSelected"
              SeparatorVisibility="Default">
        <ListView.ItemTemplate >
            <DataTemplate>
                <ImageCell Text="{Binding Marca}" Detail="{Binding Modelo}" ImageSource="{Binding Imagem, Converter={StaticResource stringToImagemConverter}}"
                            TextColor="Black" DetailColor="Blue" />
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</ContentPage>

Neste código estamos fazendo o databinding usando as propriedades: Marca, Model e Imagem, definidas na classe Carro. Também definimos o evento ItemSelected do ListView:

Observe que estamos usando o recurso ResourceDictionary para utilizar o ValueConverter definido pela classe StringToImagemConverter usada para converter string para Imagem.

O código da classe StringToImagemConverter é visto abaixo:

using System;
using System.Globalization;
using Xamarin.Forms;
namespace XF_RealmDB2.ValueConverters
{
    public class StringToImagemConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var nomeArquivo = (string)value;
            return Device.OnPlatform(
                      iOS: ImageSource.FromFile("Imagens/" + nomeArquivo),
                      Android: ImageSource.FromFile(nomeArquivo),
                      WinPhone: ImageSource.FromFile("Imagens/" + nomeArquivo));
        }
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

A classe StringToImagemConverter implementa a interface IValueConverter que define métodos para a conversão two-way entre tipos. Estamos usando aqui um recurso chamado ValueConverter que faz com que haja uma conversão de um determinado tipo, para o tipo correto da propriedade.

Esta interface possui dois métodos :

Essa classe faz a conversão das imagens definidas nas respectivas pastas em cada plataforma recebendo o nome da imagem e retornando a imagem usando ImageSource.FromFile.

Dessa forma as imagens no iOS e no Windows Phone devem ser colocadas na pasta Imagens que deve ser criada nas duas plataformas.

Agora vamos definir o código do arquivo MainPage.xaml.cs é mostrado a seguir:

using Realms;
using System.Collections.ObjectModel;
using Xamarin.Forms;
using XF_RealmDB2.Model;
namespace XF_RealmDB2
{
    public partial class MainPage : ContentPage
    {
        public ObservableCollection<Carro> CarrosCollection { get; set; }
        public MainPage()
        {
            InitializeComponent();
            CarregaCarros();

            if (CarrosCollection == null)
                CriaListaCarros();

            BindingContext = this;
        }
        private void CarregaCarros()
        {
            var realm = Realm.GetInstance();
            CarrosCollection = realm.All<Carro>() as ObservableCollection<Carro>;
        }
        private void SalvaCarros()
        {
            var realm = Realm.GetInstance();
            realm.Write(() =>
            {
                foreach (var carro in CarrosCollection)
                {
                    realm.Add(carro);
                }
            });
        }
        private void CriaListaCarros()
        {
            CarrosCollection = new ObservableCollection<Carro>()
            {
                new Carro()
                {
                    Marca = "Ford",
                    Modelo = "Ford Fiesta",
                    Imagem = "ford.jpg"
               },
                new Carro()
                {
                    Marca = "Fiat",
                    Modelo = "Fiat Uno",
                    Imagem = "fiat.jpg"
               },
                new Carro()
                {
                    Marca = "General Motors",
                    Modelo = "Cruze",
                    Imagem = "cruze.jpg"
               }
            };
            SalvaCarros();
        }
        private void ListView_ItemSelected(object sender, SelectedItemChangedEventArgs e)
        {
            var carro = e.SelectedItem as Carro;
            DisplayAlert("Item Selecionado (SelectedItem) ", carro.Modelo, "Ok");
        }
    }
}

Neste código definimos uma coleção de carros como sendo do tipo ObservableCollection<Carro>.  A coleção ObeservableCollection<T> que representa uma coleção de dados dinâmicos que fornece notificações quando os itens são adicionados, removidos, ou quando toda a coleção é atualizada. Essa coleção esta disponível no namespace System.Collection.ObjectModel.

Essa coleção trabalha essencialmente como uma coleção regular, exceto por dois pontos importantes, ela implementa as interfaces :

E isso é que a torna especial, pois além de ser uma coleção dinâmica de objetos de um dado tipo, onde os objetos podem ser adicionados, removidos ou atualizados, ela apresenta o recurso de notificar automaticamente os seus observadores quando um novo objeto foi adicionado, removido ou atualizado.

O método CarregaCarros() carrega a coleção de carros a partir do Realm; já o método CriaListaCarros() somente é chamado se a coleção de carros estiver vazia e neste gera os dados para os veículos e persiste as informação no Realm usando o método SalvaCarros() que cria uma instância do Realm e persiste os objetos carro.

No evento do ListView estamos obtendo o caroo selecionado(selectedItem) para exibir ao usuário o modelo em uma mensagem de alerta.

Executando o projeto obteremos o seguinte resultado:

Figura 1.0

Figura 2.0

Na figura 1.0 temos a página principal exibindo o ListView e as informações para 3 carros. Na figura 2.0 ao selecionar um item do ListView temos a mensagem de alerta exibida.

Pegue o código do projeto aqui : XF_RealmDB2.zip

1 Todo aquele que crê que Jesus é o Cristo, é nascido de Deus; e todo aquele que ama ao que o gerou também ama ao que dele é nascido. 2 Nisto conhecemos que amamos os filhos de Deus, quando amamos a Deus e guardamos os seus mandamentos.
1 João 5:1,2

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 ?

Referências:


José Carlos Macoratti