![]() |
Neste artigo eu vou apresentar um protótipo de uma aplicação para lanches que mostra um exemplo de utilização da interface INotifyPropertyChanged em uma aplicação Xamarin Forms. |
Vamos criar uma aplicação protótipo para venda de lanches em uma app usando alguns recursos do Xamarin Forms e a interface INotifyPropertyChanaged usada para notificar a interface quando ocorrer uma alteração no valor de uma propriedade do modelo.
Abaixo podemos ver a App em funcionamento:
A aplicação é composta por 4 páginas exibidas a seguir:
![]() |
![]() |
![]() |
![]() |
Veremos a
seguir uma explicação resumida de cada página da aplicação.
Recursos
Usados
Criando o projeto Xamarin Forms
Abra o VS 2017 Community update 15.5 e clique em New Project e a seguir escolha Cross Platform -> Cross Platform App (Xamarin.Forms) e informe o nome XF_Lanches.
Ao criar um projeto Xamarin Forms em uma versão anterior à atualização 15.5, você tinha duas opções para compartilhar o código entre as plataformas:
Pois a partir da versão 15.5 do Visual Studio(lançada em dezembro/2017) a opção Portable Class Library (PCL) foi substituida pela .NET Standard:
![]() |
Marque as opções Android e/ou iOS, marque Xamarin Forms e a seguir marque .NET Standard e clique no botão OK.
Pronto nosso projeto já esta criado.
Definindo o modelo de domínio
Vamos criar uma pasta Models no projeto e a seguir criar as seguintes classes que vão representa o nosso modelo de domínio:
1- Usuario
namespace XF_Lanches.Models
{
public class Usuario
{
public string Nome { get; set; }
public string Email { get; set; }
public string Telefone { get; set; }
}
}
|
2- Lanche
using System;
using System.ComponentModel;
namespace XF_Lanches.Models
{
public class Lanche : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string prop)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
public string Nome { get; set; }
public string Descricao { get; set; }
public string Status { get; set; }
public decimal Preco { get; set; }
public string ImagemUrl { get; set; }
private const decimal OVO = 1.50M;
private const decimal BACON = 2.00M;
private const decimal CATUPIRY = 2.50M;
private const decimal CHEDDAR = 2.00M;
private const decimal MAIONESE = 1.00M;
public string TextoOvo
{
get { return String.Format("Ovo - R$ {0}", OVO); }
}
public string TextoBacon
{
get { return String.Format("Bacon - R$ {0}", BACON); }
}
public string TextoCatupiry
{
get { return String.Format("Catupri - R$ {0}", CATUPIRY); }
}
public string TextoCheddar
{
get { return String.Format("Cheddar - R$ {0}", CHEDDAR); }
}
public string TextoMaionese
{
get { return String.Format("Maionese - R$ {0}", MAIONESE); }
}
public string ValorTotal
{
get
{
return string.Format("Valor Total: R$ {0}",Preco
+ (TemOvo ? OVO : 0) + (TemBacon ? BACON : 0)
+ (TemMaionese ? MAIONESE : 0) + (TemCheddar ? CHEDDAR : 0) + (TemCatupiry ? CATUPIRY : 0));
}
}
private bool temOvo;
public bool TemOvo
{
get{return temOvo;}
set{
temOvo = value;
RaisePropertyChanged(nameof(ValorTotal));
}
}
private bool temMaionese;
public bool TemMaionese
{
get
{return temMaionese;}
set
{
temMaionese = value;
RaisePropertyChanged(nameof(ValorTotal));
}
}
private bool temBacon;
public bool TemBacon
{
get
{return temBacon;}
set
{
temBacon = value;
RaisePropertyChanged(nameof(ValorTotal));
}
}
private bool temCheddar;
public bool TemCheddar
{
get
{return temCheddar;}
set
{
temCheddar = value;
RaisePropertyChanged(nameof(ValorTotal));
}
}
private bool temCatupiry;
public bool TemCatupiry
{
get
{return temCatupiry;}
set
{
temCatupiry = value;
RaisePropertyChanged(nameof(ValorTotal));
}
}
}
}
|
3- Acrescimo
namespace XF_Lanches.Models
{
public class Acrescimo
{
public int AcrescimoId { get; set; }
public string Nome { get; set; }
public string Valor { get; set; }
//
public decimal Maionese { get; } = 1.00M;
public decimal Ovo { get; }
public decimal Cheddar { get; }
public decimal Catupiry { get; }
public decimal Bacon { get; }
}
}
|
Instale o pacote em todos os projetos clicando em Install.
Exibindo os lanches na página inicial : MainPage.xaml
Abra o arquivo MainPage.xaml e inclua no código abaixo:
<?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_Lanches"
x:Class="XF_Lanches.MainPage"
Title="MacLanches - Peça o seu Agora !!!">
<ListView x:Name="lvLanches" HasUnevenRows="True" ItemSelected="Handle_ItemSelected" SeparatorColor="Blue">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal" HorizontalOptions="Center" VerticalOptions="Center">
<StackLayout HorizontalOptions="CenterAndExpand" Orientation="Horizontal">
<Image Source="{Binding ImagemUrl}" HeightRequest="100" WidthRequest="100"/>
<Label Text="{Binding Nome}" TextColor="Black" HorizontalOptions="Center" VerticalOptions="Center"/>
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage>
|
No arquivo
MainPage.xaml.cs temos o código onde definimos
alguns lanches para serem exibidos e tratamos o item
selecionado :
using System.Collections.Generic;
using Xamarin.Forms;
using XF_Lanches.Models;
namespace XF_Lanches
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
lvLanches.ItemsSource = new List<Lanche>
{
new Lanche { Nome="Cheese Burger", Descricao="", Status="Ativo", Preco=12.90M ,
ImagemUrl="http://www.macoratti.net/Imagens/lanches/cheeseBurger.jpg" },
new Lanche { Nome="Cheese Salada", Descricao="", Status="Ativo", Preco=14.50M ,
ImagemUrl="http://www.macoratti.net/Imagens/lanches/chesseSalada.jpg" },
new Lanche { Nome="Cheese Egg", Descricao="", Status="Ativo", Preco=15.50M ,
ImagemUrl="http://www.macoratti.net/Imagens/lanches/cheeseEgg.jpg" },
new Lanche { Nome="Cheese Tudo", Descricao="", Status="Ativo", Preco=18.00M ,
ImagemUrl="http://www.macoratti.net/Imagens/lanches/cheeseTudo.jpg" },
new Lanche { Nome="Lanche de Frango", Descricao="", Status="Ativo", Preco=13.90M ,
ImagemUrl="http://www.macoratti.net/Imagens/lanches/lancheFrango.jpg" },
new Lanche { Nome="Misto Quente", Descricao="", Status="Ativo", Preco=10.50M ,
ImagemUrl="http://www.macoratti.net/Imagens/lanches/lancheMistoQuente.jpg" }
};
}
public async void Handle_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
var lanche = e.SelectedItem as Lanche;
if (lanche == null)
return;
await this.Navigation.PushAsync(new LancheDetailsPage(lanche));
}
}
}
|
Incluindo acréscimos ao lanche : LancheDetailsPage.xaml
Esta página exibe o lanche selecionado e as opções de acréscimos que o usuário pode incluir ao lanche. Aqui usamos o two way databinding e aplicamos a notificação via INotifyPropertyChanged:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XF_Lanches.LancheDetailsPage"
Title="{Binding Nome}">
<ContentPage.Content>
<StackLayout Padding="10">
<Image Source="{Binding ImagemUrl}" HeightRequest="100" WidthRequest="100"/>
<TableView>
<TableRoot>
<TableSection Title="Acréscimos">
<SwitchCell Text="{Binding TextoMaionese}" On="{Binding TemMaionese, Mode=TwoWay}"></SwitchCell>
<SwitchCell Text="{Binding TextoBacon}" On="{Binding TemBacon, Mode=TwoWay}"></SwitchCell>
<SwitchCell Text="{Binding TextoOvo}" On="{Binding TemOvo, Mode=TwoWay}"></SwitchCell>
<SwitchCell Text="{Binding TextoCheddar}" On="{Binding TemCheddar, Mode=TwoWay}"></SwitchCell>
<SwitchCell Text="{Binding TextoCatupiry}" On="{Binding TemCatupiry, Mode=TwoWay}"></SwitchCell>
<TextCell Text="{Binding ValorTotal}" TextColor="Blue" ></TextCell>
</TableSection>
</TableRoot>
</TableView>
<Button x:Name="btnProximo" Text="Próximo" Clicked="btnProximo_Clicked" VerticalOptions="End"
TextColor="White" BackgroundColor="Green" FontAttributes="Bold"></Button>
</StackLayout>
</ContentPage.Content>
</ContentPage>
|
No arquivo
LanchesDetailsPage.xaml.cs temos o código que trata
o evento Click e avança para próxima página:
using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using XF_Lanches.Models;
namespace XF_Lanches
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class LancheDetailsPage : ContentPage
{
Lanche _lanche;
public LancheDetailsPage (Lanche lanche)
{
InitializeComponent ();
_lanche = lanche;
this.BindingContext = _lanche;
}
async void btnProximo_Clicked(object sender, EventArgs e)
{
if (_lanche == null)
return;
await this.Navigation.PushAsync(new LanchePedidoPage(_lanche));
}
}
}
|
Apresentando a página de pedido : LanchePedidoPage.xaml
Nesta página apresentamos o pedido feito pelo usuário e solicitamos seu nome, email e telefone antes de confirmar o pedido:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XF_Lanches.LanchePedidoPage"
Title="{Binding Nome}">
<ContentPage.Content>
<StackLayout Padding="10">
<TableView>
<TableRoot>
<TableSection Title="Seu Pedido">
<ImageCell ImageSource="{Binding ImagemUrl}" />
<TextCell Text="{Binding Nome}" TextColor="Blue"></TextCell>
<TextCell Text="{Binding ValorTotal}" TextColor="Blue"></TextCell>
</TableSection>
<TableSection Title="Seu Dados">
<EntryCell x:Name="strNome" Label="Nome" Placeholder="Informe o seu nome"></EntryCell>
<EntryCell x:Name="strFone" Label="Fone:" Placeholder="Informe o seu telefone" Keyboard="Telephone"></EntryCell>
<EntryCell x:Name="strEmail" Label="Email:" Placeholder="Informe o seu email" Keyboard="Email"></EntryCell>
</TableSection>
</TableRoot>
</TableView>
<Button x:Name="btnPedido" Text="Concluir Pedido" Clicked="btnPedido_Clicked" VerticalOptions="End"
TextColor="White" BackgroundColor="Blue" FontAttributes="Bold"></Button>
</StackLayout>
</ContentPage.Content>
</ContentPage>
|
No código do arquivo LanchePedidoPage.xaml.cs obtemos as informações do cliente e após validação navegamos para a página de confirmação do pedido:
using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using XF_Lanches.Models;
namespace XF_Lanches
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class LanchePedidoPage : ContentPage
{
Lanche _lanche;
Usuario _usuario;
public LanchePedidoPage (Lanche lanche)
{
InitializeComponent ();
this._lanche = lanche;
this.BindingContext = _lanche;
}
async void btnPedido_Clicked(object sender, EventArgs e)
{
if (_lanche == null)
return;
if (string.IsNullOrEmpty(strNome.Text))
return;
if (string.IsNullOrEmpty(strEmail.Text))
return;
if (string.IsNullOrEmpty(strFone.Text))
return;
_usuario = new Usuario();
_usuario.Nome = strNome.Text;
_usuario.Telefone = strFone.Text;
_usuario.Email = strEmail.Text;
await this.Navigation.PushModalAsync(new LanchePedidoConfirmacao(_lanche));
}
}
}
|
Apresentando a página de confirmação do pedido : LanchePedidoConfirmacao.xaml
Na página de confirmação do pedido apresentamos a imagem do lanche e o valor total do pedido:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XF_Lanches.LanchePedidoConfirmacao"
Title="{Binding Nome}"
BackgroundColor="Cyan">
<ContentPage.Content>
<StackLayout Padding="20" VerticalOptions="Center" HorizontalOptions="Center">
<Frame>
<Image Source="{Binding ImagemUrl}" HeightRequest="200" WidthRequest="200" VerticalOptions="Center"
HorizontalOptions="Center"/>
</Frame>
<Frame>
<Label Text="{Binding ValorTotal}" FontSize="Large" TextColor="Blue" VerticalOptions="Center"
HorizontalOptions="Center"/>
</Frame>
<Label Text="Seu pedido foi recebido com sucesso, em poucos minutos estará chegando..."
TextColor="Black" FontSize="Medium"
VerticalOptions="Center" HorizontalOptions="Center"/>
</StackLayout>
</ContentPage.Content>
</ContentPage>
|
No código do arquivo
LanchePedidoConfirmacao.xaml.cs apenas recebemos o
lanche e fazemos a vinculação no
BindingContext:
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using XF_Lanches.Models;
namespace XF_Lanches
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class LanchePedidoConfirmacao : ContentPage
{
public LanchePedidoConfirmacao (Lanche lanche)
{
InitializeComponent ();
this.BindingContext = lanche;
}
}
}
|
Este exemplo é bem simples e foi feito apenas para mostrar como usar o recurso de notificação da interface INotifyPropertyChanged.
Podemos otimizar o código usado no projeto mas o objetivo era mesmo mostrar a interface INotifyPropertyChanged na sua forma nua e crua.
Pegue o código do projeto
compartilhado aqui :
XF_Lanches.zip (sem as referências)
"Tomando
sobretudo o escudo da fé, com o qual podereis apagar
todos os dardos inflamados do maligno. "
Efésios 6:16
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:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Xamarin Android - Apresentando o controle ProgressBar - Macoratti.net
Xamarin Android - Usando o serviço de Alarme - Macoratti.net
Xamarin.Forms - Usando a view ActivityIndicator - Macoratti.net