Xamarin Forms - Apresentando o recurso MultiBinding
Hoje vou apresentar o recurso Multi-Binding do Xamarin Forms. |
O Multi-binding é um recurso que foi introduzido no Xamarin Forms 4.7 que permite a vinculação de múltiplas fontes a uma única propriedade de destino.
Este recurso nós oferece bastante flexibilidade, pois agora não precisamos criar vários elementos de IU para cada propriedade vinculável, o que melhora o desempenho e torna nosso código mais limpo.
Antes deste recurso para conseguir ligar várias fontes à mesma propriedade, era necessário um esforço extra. Já que o único controle que possui algo semelhante é o Label com a propriedade FormattedText.
<Label>
<Label.FormattedText>
<FormattedString>
<Span Text="{Binding Nome}"/>
<Span Text=" "/>
<Span Text="{Binding Sobrenome}"/>
</FormattedString>
</Label.FormattedText>
</Label>
|
Mas e se precisarmos fazer o mesmo com outro controle que não possui a propriedade FormattedText ?
Para estes casos podemos usar o novo recurso MultiBinding.
Este recurso fornece a capacidade de anexar uma coleção de objetos Binding a uma única propriedade de destino de ligação. Eles são criados com a classe MultiBinding, que avalia todos os seus objetos Binding e retorna um único valor por meio de uma instância de IMultiValueConverter fornecida pelo seu aplicativo. Além disso, a classe MultiBinding reavalia todos os seus objetos Binding quando qualquer um dos dados vinculados for alterado.
A classe MultiBinding define as seguintes propriedades:
Bindings - Representa a coleção de objetos Binding dentro da instância de MultiBinding;
Converter - Representa o Converter usado para converter os valores de origem de ou para o valor de destino;
ConverterParameter - Representa o parâmetro opcional passado para o Converter;
A propriedade Bindings é a propriedade de conteúdo da classe MultiBinding e, portanto, não precisa ser definida explicitamente no XAML.
Um MultiBinding deve usar um IMultiValueConverter para produzir um valor para o destino do binding, com base no valor das associações na coleção Bindings.
Além disso a classe MultiBinding também herda as seguintes propriedades da classe BindingBase:
FallbackValue - È o valor a usar quando não for possível retornar um valor;
Mode - Indica a direção do fluxo de dados;
StringFormat - define como formatar o resultado de uma string;
TargetNullValue - Valor usado no destino quando o valor da origem for null;
Usando o MultiBinding
Em um projeto Xamarin Forms criado usando o template Blank vamos definir no arquivo MainPage.xaml.cs o código a seguir:
public partial class MainPage : ContentPage
{
public string Nome { get; set; } = "Jose Carlos";
public string Sobrenome { get; set; } = "Macoratti";
public MainPage()
{
InitializeComponent();
BindingContext = this;
}
}
|
A seguir no arquivo MainPage.xaml vamos usar o MultiBinding com uma Label e com um Button:
<?xml version="1.0" encoding="utf-8"
?>
<StackLayout>
<Button> </ContentPage> |
Note que no código XAML devemos adicionar o MultiBinding a qualquer propriedade que desejamos usar, e a seguir, especificar o formato usando StringFormat adicionando um {} para escapar da sequência, e a seguir adicionar todas as propriedades que deseja usando o {[sequenceNumber]} para cada propriedade.
O resultado é o seguinte:
Observe que para cada Binding podemos especificar um Converter, ConverterParameter, FallbackValue, etc.
Vamos a seguir mostrar um exemplo usando este recurso onde vamos criar um conversor de tipo que para o nosso contexto vai usar a interface IMultiValueConverter.
Exemplo prático usando MultiBinding
Neste exemplo vamos criar uma página de login onde vamos usar o nome e sobrenome do usuário para login. Vamos criar um conversor usando a interface IMultiValueConverter.
A seguir vamos adicionar o conversor á propriedade MultiBinding de forma a converter a lista de bindings para o valor que desejamos exibir.
Assim no projeto Xamarin Forms vamos criar a pasta ViewModels onde vamos criar a classe MainViewModel:
using Xamarin.Forms;
namespace XF_MultiBinding.ViewModels
{
public class MainViewModel : BindableObject
{
private string _nome;
private string _sobrenome;
public string Nome
{
get { return _nome; }
set
{
_nome = value;
OnPropertyChanged();
}
}
public string Sobrenome
{
get { return _sobrenome; }
set
{
_sobrenome = value;
OnPropertyChanged();
}
}
}
}
|
A classe MainViewModel define duas propriedades Nome e Sobrenome e herda de BindableObject que fornece um mecanismo para propagar as alterações feitas aos dados em um objeto para outro, habilitando validação, coerção de tipo e um sistema de evento.
A seguir crie a pasta Converters no projeto e nesta pasta crie a classe NomeConverter que implementa a interface IMultiValueConverter:
using System;
using System.Globalization;
using Xamarin.Forms;
namespace XF_MultiBinding.Converters
{
internal class NomeConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return $"{values[0]} {values[1]}";
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
return null;
}
}
}
|
A seguir no arquivo MainPage.xaml inclua o código a seguir:
<?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:viewmodels="clr-namespace:XF_MultiBinding.ViewModels"
xmlns:converters="clr-namespace:XF_MultiBinding.Converters"
x:Class="XF_MultiBinding.MainPage">
<ContentPage.Resources>
<ResourceDictionary>
<converters:NomeConverter x:Key="NomeConverter" />
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.BindingContext>
<viewmodels:MainViewModel />
</ContentPage.BindingContext>
<ContentPage.Content>
<StackLayout Padding="12">
<Label Text="Preencha o formulário:" TextColor="DarkBlue"
HorizontalOptions="Start" FontSize="Medium" />
<Entry Placeholder="Nome"
Text="{Binding Nome, Mode=TwoWay}"/>
<Entry Placeholder="Sobrenome"
Text="{Binding Sobrenome, Mode=TwoWay}"/>
<BoxView HorizontalOptions="FillAndExpand" VerticalOptions="Center"
HeightRequest="1" />
<Label Text="Nome completo" TextColor="DarkBlue" HorizontalOptions="Start"
FontSize="Medium" />
<Label>
<Label.Text>
<MultiBinding Converter="{StaticResource NomeConverter}">
<Binding Path="Nome"/>
<Binding Path="Sobrenome"/>
</MultiBinding>
</Label.Text>
</Label>
<BoxView HorizontalOptions="FillAndExpand" VerticalOptions="Center"
HeightRequest="1" />
<StackLayout VerticalOptions="EndAndExpand" Margin="0,0,0,10">
<Button Text="Registrar" HeightRequest="50" BackgroundColor="DarkBlue"
TextColor="White" CornerRadius="5" />
<Label Text="Esqueceu a senha ?" TextColor="DarkBlue"
HorizontalOptions="Center" FontSize="Medium" />
<StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand">
<BoxView BackgroundColor="#555" HorizontalOptions="FillAndExpand"
VerticalOptions="Center" HeightRequest="1" />
<Label Text="OU" TextColor="#555" HorizontalOptions="Center"
VerticalOptions="Center" FontSize="Medium" />
<BoxView BackgroundColor="#555" HorizontalOptions="FillAndExpand"
VerticalOptions="Center" HeightRequest="1" />
</StackLayout>
<Button Text="Log In" HeightRequest="50" BackgroundColor="DarkBlue"
TextColor="White" CornerRadius="5" />
</StackLayout>
</StackLayout>
</ContentPage.Content>
</ContentPage>
|
Destaques do código :
1 - Criamos o recurso usando o conversor NomeConverter :
<ContentPage.Resources>
<ResourceDictionary>
<converters:NomeConverter x:Key="NomeConverter" />
</ResourceDictionary>
</ContentPage.Resources>
|
2 - Definimos a vinculação com a MainViewModel :
<ContentPage.BindingContext>
<viewmodels:MainViewModel />
</ContentPage.BindingContext>
|
3 - Incluímos o conversor NomeConverter na propriedade Multibinding da Label que vai apresentar o resultado para exibir o nome completo:
<Label>
<Label.Text>
<MultiBinding Converter="{StaticResource NomeConverter}">
<Binding Path="Nome"/>
<Binding Path="Sobrenome"/>
</MultiBinding>
</Label.Text>
</Label>
|
O resultado da execução usando emulador Genymotion é o seguinte:
Este é um exemplo básico de utilização do recurso MultiBinding onde temos diversas outras possibilidades de aplicação que iremos mostrar em outros artigos sobre o assunto.
Pegue o projeto aqui: XF_MultiBinding.zip (sem as referências)
"Eu rogo por eles;
não rogo pelo mundo, mas por aqueles que me deste, porque são teus.
E todas as minhas coisas são tuas, e as tuas coisas são minhas; e neles sou
glorificado."
João 17:9,10
Referências:
Xamarin Forms - Definindo um luxo de Login
Xamarin Forms - Usando a Câmera
Xamarin Forms - Usando SQLite com MVVM
Xamarin Forms - Criando uma página de pequisa
Xamarin Forms 4.0 - Apresentando o Shell
Xamarin Forms - Apresentando CollectionView