Várias associações do Xamarin.Forms
As várias associações fornecem a capacidade de anexar uma coleção de objetos a uma única propriedade de destino de Binding
associação. Eles são criados com a MultiBinding
classe, que avalia todos os seus Binding
objetos e retorna um único valor por meio de uma IMultiValueConverter
instância fornecida pelo seu aplicativo. Além disso, MultiBinding
reavalia todos os seus Binding
objetos quando qualquer um dos dados associados é alterado.
A classe MultiBinding
define as seguintes propriedades:
Bindings
, do tipoIList<BindingBase>
, que representa a coleção deBinding
objetos dentro daMultiBinding
instância.Converter
, do tipoIMultiValueConverter
, que representa o conversor a ser usado para converter os valores de origem de ou para o valor de destino.ConverterParameter
, do tipoobject
, que representa um parâmetro opcional a ser passado para oConverter
.
A propriedade Bindings
é a propriedade de conteúdo da classe MultiBinding
e, portanto, não precisa ser definida explicitamente no XAML.
Além disso, a MultiBinding
classe herda as seguintes propriedades da BindingBase
classe:
FallbackValue
, do tipoobject
, que representa o valor a ser usado quando a associação múltipla não puder retornar um valor.Mode
, do tipoBindingMode
, que indica a direção do fluxo de dados da associação múltipla.StringFormat
, do tipostring
, que especifica como formatar o resultado de várias associações se ele for exibido como uma cadeia de caracteres.TargetNullValue
, do tipoobject
, que representa o valor usado no destino quando o valor da origem énull
.
A MultiBinding
deve usar a para IMultiValueConverter
produzir um valor para o destino de associação, com base no valor das associações na Bindings
coleção. Por exemplo, a Color
pode ser calculado a partir de valores vermelhos, azuis e verdes, que podem ser valores do mesmo ou de objetos de origem de associação diferentes. Quando um valor é movido do destino para as origens, o valor da propriedade de destino é convertido em um conjunto de valores que são realimentados nas associações.
Importante
As associações individuais na Bindings
coleção podem ter seus próprios conversores de valor.
O valor da Mode
propriedade determina a funcionalidade do MultiBinding
, e é usado como o modo de associação para todas as associações na coleção, a menos que uma associação individual substitua a propriedade. Por exemplo, se a Mode
propriedade em um MultiBinding
objeto for definida como TwoWay
, todas as associações na coleção serão consideradas TwoWay
, a menos que você defina explicitamente um valor diferente Mode
em uma das associações.
Definir um IMultiValueConverter
A IMultiValueConverter
interface permite que a lógica personalizada seja aplicada a um MultiBinding
. Para associar um conversor a um MultiBinding
, crie uma classe que implemente a IMultiValueConverter
interface e, em seguida, implemente os Convert
métodos and ConvertBack
:
public class AllTrueMultiConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values == null || !targetType.IsAssignableFrom(typeof(bool)))
{
return false;
// Alternatively, return BindableProperty.UnsetValue to use the binding FallbackValue
}
foreach (var value in values)
{
if (!(value is bool b))
{
return false;
// Alternatively, return BindableProperty.UnsetValue to use the binding FallbackValue
}
else if (!b)
{
return false;
}
}
return true;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
if (!(value is bool b) || targetTypes.Any(t => !t.IsAssignableFrom(typeof(bool))))
{
// Return null to indicate conversion back is not possible
return null;
}
if (b)
{
return targetTypes.Select(t => (object)true).ToArray();
}
else
{
// Can't convert back from false because of ambiguity
return null;
}
}
}
O Convert
método converte valores de origem em um valor para o destino de associação. O Xamarin.Forms chama esse método quando propaga valores de associações de origem para o destino de associação. Este método aceita quatro argumentos:
values
, do tipoobject[]
, é uma matriz de valores que as associações de origem produzemMultiBinding
.targetType
, do tipoType
, é o tipo da propriedade de destino de associação.parameter
, do tipoobject
, é o parâmetro do conversor a ser usado.culture
, do tipoCultureInfo
, é a cultura a ser usada no conversor.
O Convert
método retorna um object
que representa um valor convertido. Este método deve retornar:
BindableProperty.UnsetValue
para indicar que o conversor não produziu um valor e que a associação usará oFallbackValue
.Binding.DoNothing
para instruir o Xamarin.Forms a não executar nenhuma ação. Por exemplo, para instruir o Xamarin.Forms a não transferir um valor para o destino de associação ou a não usar oFallbackValue
.null
para indicar que o conversor não pode executar a conversão e que a associação usará oTargetNullValue
.
Importante
A MultiBinding
que recebe BindableProperty.UnsetValue
de um Convert
método deve definir sua FallbackValue
propriedade. Da mesma forma, um MultiBinding
que recebe null
de um Convert
método deve definir sua TargetNullValue
propriedade.
O ConvertBack
método converte um destino de associação nos valores de associação de origem. Este método aceita quatro argumentos:
value
, do tipoobject
, é o valor que o destino de associação produz.targetTypes
, do tipoType[]
, é a matriz de tipos para converter. O comprimento da matriz indica o número e tipos de valores sugeridos para o método retornar.parameter
, do tipoobject
, é o parâmetro do conversor a ser usado.culture
, do tipoCultureInfo
, é a cultura a ser usada no conversor.
O ConvertBack
método retorna uma matriz de valores, do tipo object[]
, que foram convertidos do valor de destino de volta para os valores de origem. Este método deve retornar:
BindableProperty.UnsetValue
i
at para indicar que o conversor não pode fornecer um valor para a vinculação de origem no índicei
e que nenhum valor deve ser definido nele.Binding.DoNothing
na posiçãoi
para indicar que nenhum valor deve ser definido na associação de origem no índicei
.null
para indicar que o conversor não pode executar a conversão ou que não suporta a conversão nessa direção.
Consumir um IMultiValueConverter
A IMultiValueConverter
é consumido instanciando-o em um dicionário de recursos e, em seguida, referenciando-o usando a extensão de StaticResource
marcação para definir a MultiBinding.Converter
propriedade:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:DataBindingDemos"
x:Class="DataBindingDemos.MultiBindingConverterPage"
Title="MultiBinding Converter demo">
<ContentPage.Resources>
<local:AllTrueMultiConverter x:Key="AllTrueConverter" />
<local:InverterConverter x:Key="InverterConverter" />
</ContentPage.Resources>
<CheckBox>
<CheckBox.IsChecked>
<MultiBinding Converter="{StaticResource AllTrueConverter}">
<Binding Path="Employee.IsOver16" />
<Binding Path="Employee.HasPassedTest" />
<Binding Path="Employee.IsSuspended"
Converter="{StaticResource InverterConverter}" />
</MultiBinding>
</CheckBox.IsChecked>
</CheckBox>
</ContentPage>
Neste exemplo, o MultiBinding
objeto usa a AllTrueMultiConverter
instância para definir a CheckBox.IsChecked
propriedade como true
, desde que os três Binding
objetos sejam avaliados como true
. Caso contrário, a CheckBox.IsChecked
propriedade será definida como false
.
Por padrão, a CheckBox.IsChecked
propriedade usa uma TwoWay
associação. Portanto, o ConvertBack
AllTrueMultiConverter
método da instância é executado quando o CheckBox
é desmarcado pelo usuário, que define os valores de associação de origem como o valor da CheckBox.IsChecked
propriedade.
O código C# equivalente é mostrado abaixo:
public class MultiBindingConverterCodePage : ContentPage
{
public MultiBindingConverterCodePage()
{
BindingContext = new GroupViewModel();
CheckBox checkBox = new CheckBox();
checkBox.SetBinding(CheckBox.IsCheckedProperty, new MultiBinding
{
Bindings = new Collection<BindingBase>
{
new Binding("Employee1.IsOver16"),
new Binding("Employee1.HasPassedTest"),
new Binding("Employee1.IsSuspended", converter: new InverterConverter())
},
Converter = new AllTrueMultiConverter()
});
Title = "MultiBinding converter demo";
Content = checkBox;
}
}
Cadeias de caracteres de formato
A MultiBinding
pode formatar qualquer resultado de associação múltipla exibido como uma cadeia de caracteres, com a StringFormat
propriedade. Essa propriedade pode ser definida como uma cadeia de caracteres de formatação padrão do .NET, com espaços reservados, que especifica como formatar o resultado de várias associações:
<Label>
<Label.Text>
<MultiBinding StringFormat="{}{0} {1} {2}">
<Binding Path="Employee1.Forename" />
<Binding Path="Employee1.MiddleName" />
<Binding Path="Employee1.Surname" />
</MultiBinding>
</Label.Text>
</Label>
Neste exemplo, a StringFormat
propriedade combina os três valores associados em uma única cadeia de caracteres exibida pelo Label
.
O código C# equivalente é mostrado abaixo:
Label label = new Label();
label.SetBinding(Label.TextProperty, new MultiBinding
{
Bindings = new Collection<BindingBase>
{
new Binding("Employee1.Forename"),
new Binding("Employee1.MiddleName"),
new Binding("Employee1.Surname")
},
StringFormat = "{0} {1} {2}"
});
Importante
O número de parâmetros em um formato de cadeia de caracteres composta não pode exceder o número de objetos filho Binding
no MultiBinding
.
Ao definir as Converter
propriedades and StringFormat
, o conversor é aplicado primeiro ao valor de dados e, em seguida, o StringFormat
é aplicado.
Para obter mais informações sobre a formatação de cadeia de caracteres no Xamarin.Forms, consulte Formatação de cadeia de caracteres do Xamarin.Forms.
Fornecer valores de fallback
As associações de dados podem ser mais robustas definindo valores de fallback a serem usados se o processo de associação falhar. Isso pode ser feito definindo opcionalmente as FallbackValue
propriedades and TargetNullValue
em um MultiBinding
objeto.
A MultiBinding
usará seu FallbackValue
quando o Convert
método de uma IMultiValueConverter
instância retornar BindableProperty.UnsetValue
, o que indica que o conversor não produziu um valor. A MultiBinding
usará seu TargetNullValue
quando o Convert
método de uma IMultiValueConverter
instância retornar null
, o que indica que o conversor não pode realizar a conversão.
Para obter mais informações sobre fallbacks de associação, consulte Fallbacks de associação do Xamarin.Forms.
Aninhar objetos MultiBinding
MultiBinding
Os objetos podem ser aninhados para que vários MultiBinding
objetos sejam avaliados para retornar um valor por meio de uma IMultiValueConverter
instância:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:DataBindingDemos"
x:Class="DataBindingDemos.NestedMultiBindingPage"
Title="Nested MultiBinding demo">
<ContentPage.Resources>
<local:AllTrueMultiConverter x:Key="AllTrueConverter" />
<local:AnyTrueMultiConverter x:Key="AnyTrueConverter" />
<local:InverterConverter x:Key="InverterConverter" />
</ContentPage.Resources>
<CheckBox>
<CheckBox.IsChecked>
<MultiBinding Converter="{StaticResource AnyTrueConverter}">
<MultiBinding Converter="{StaticResource AllTrueConverter}">
<Binding Path="Employee.IsOver16" />
<Binding Path="Employee.HasPassedTest" />
<Binding Path="Employee.IsSuspended" Converter="{StaticResource InverterConverter}" />
</MultiBinding>
<Binding Path="Employee.IsMonarch" />
</MultiBinding>
</CheckBox.IsChecked>
</CheckBox>
</ContentPage>
Neste exemplo, o MultiBinding
objeto usa sua AnyTrueMultiConverter
instância para definir a CheckBox.IsChecked
propriedade como true
, desde que todos os Binding
objetos no objeto interno MultiBinding
sejam avaliados como true
, ou desde que o Binding
objeto no objeto externo MultiBinding
seja avaliado como true
. Caso contrário, a CheckBox.IsChecked
propriedade será definida como false
.
Usar uma associação RelativeSource em um MultiBinding
MultiBinding
Os objetos dão suporte a associações relativas, que fornecem a capacidade de definir a origem da associação em relação à posição do destino da associação:
<ContentPage ...
xmlns:local="clr-namespace:DataBindingDemos"
xmlns:xct="clr-namespace:Xamarin.CommunityToolkit.UI.Views;assembly=Xamarin.CommunityToolkit">
<ContentPage.Resources>
<local:AllTrueMultiConverter x:Key="AllTrueConverter" />
<ControlTemplate x:Key="CardViewExpanderControlTemplate">
<xct:Expander BindingContext="{Binding Source={RelativeSource TemplatedParent}}"
IsExpanded="{Binding IsExpanded, Source={RelativeSource TemplatedParent}}"
BackgroundColor="{Binding CardColor}">
<xct:Expander.IsVisible>
<MultiBinding Converter="{StaticResource AllTrueConverter}">
<Binding Path="IsExpanded" />
<Binding Path="IsEnabled" />
</MultiBinding>
</xct:Expander.IsVisible>
<xct:Expander.Header>
<Grid>
<!-- XAML that defines Expander header goes here -->
</Grid>
</xct:Expander.Header>
<Grid>
<!-- XAML that defines Expander content goes here -->
</Grid>
</xct:Expander>
</ControlTemplate>
</ContentPage.Resources>
<StackLayout>
<controls:CardViewExpander BorderColor="DarkGray"
CardTitle="John Doe"
CardDescription="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla elit dolor, convallis non interdum."
IconBackgroundColor="SlateGray"
IconImageSource="user.png"
ControlTemplate="{StaticResource CardViewExpanderControlTemplate}"
IsEnabled="True"
IsExpanded="True" />
</StackLayout>
</ContentPage>
Observação
O Expander
controle agora faz parte do Xamarin Community Toolkit.
Neste exemplo, o TemplatedParent
modo de associação relativa é usado para associar de dentro de um modelo de controle à instância do objeto de tempo de execução à qual o modelo é aplicado. O Expander
, que é o elemento raiz do , tem seu BindingContext
conjunto para a instância do ControlTemplate
objeto de tempo de execução ao qual o modelo é aplicado. Portanto, o Expander
e seus filhos resolvem suas expressões de associação e Binding
objetos em relação às propriedades do CardViewExpander
objeto. O MultiBinding
usa a AllTrueMultiConverter
instância para definir a Expander.IsVisible
propriedade como true
desde que os dois Binding
objetos sejam avaliados como true
. Caso contrário, a Expander.IsVisible
propriedade será definida como false
.
Para obter mais informações sobre associações relativas, veja Associações Relativas do Xamarin.Forms. Para obter mais informações sobre modelos de controle, consulte Modelos de controle do Xamarin.Forms.