Multi binding di Xamarin.Forms
Le associazioni multi-binding consentono di associare una raccolta di Binding
oggetti a una singola proprietà di destinazione di associazione. Vengono creati con la MultiBinding
classe , che valuta tutti i relativi Binding
oggetti e restituisce un singolo valore tramite un'istanza IMultiValueConverter
fornita dall'applicazione. Inoltre, MultiBinding
rivaluta tutti i relativi Binding
oggetti quando uno dei dati associati cambia.
La MultiBinding
classe definisce le proprietà seguenti:
Bindings
, di tipoIList<BindingBase>
, che rappresenta la raccolta diBinding
oggetti all'interno dell'istanzaMultiBinding
di .Converter
, di tipoIMultiValueConverter
, che rappresenta il convertitore da utilizzare per convertire i valori di origine in o dal valore di destinazione.ConverterParameter
, di tipoobject
, che rappresenta un parametro facoltativo da passare aConverter
.
La Bindings
proprietà è la proprietà content della MultiBinding
classe e pertanto non deve essere impostata in modo esplicito da XAML.
Inoltre, la MultiBinding
classe eredita le proprietà seguenti dalla BindingBase
classe :
FallbackValue
, di tipoobject
, che rappresenta il valore da utilizzare quando l'associazione multipla non è in grado di restituire un valore.Mode
, di tipoBindingMode
, che indica la direzione del flusso di dati dell'associazione multipla.StringFormat
, di tipostring
, che specifica come formattare il risultato dell'associazione multipla se viene visualizzato come stringa.TargetNullValue
, di tipoobject
, che rappresenta il valore usato nella destinazione wen il valore dell'origine ènull
.
Un MultiBinding
oggetto deve utilizzare un IMultiValueConverter
oggetto per produrre un valore per la destinazione di associazione, in base al valore delle associazioni nella Bindings
raccolta. Ad esempio, un Color
può essere calcolato da valori di origine rosso, blu e verde, che possono essere valori degli stessi oggetti di origine di associazione o diversi. Quando un valore passa dalla destinazione alle origini, il valore della proprietà di destinazione viene convertito in un set di valori che vengono reinseriti nelle associazioni.
Importante
I singoli binding nella Bindings
raccolta possono avere convertitori di valori personalizzati.
Il valore della Mode
proprietà determina la funzionalità di MultiBinding
e viene utilizzato come modalità di associazione per tutte le associazioni dell'insieme, a meno che una singola associazione non esegua l'override della proprietà. Ad esempio, se la Mode
proprietà di un MultiBinding
oggetto è impostata su TwoWay
, tutte le associazioni nell'insieme vengono considerate TwoWay
a meno che non si imposti in modo esplicito un valore diverso Mode
su una delle associazioni.
Definire un oggetto IMultiValueConverter
L'interfaccia IMultiValueConverter
consente di applicare la logica personalizzata a un oggetto MultiBinding
. Per associare un convertitore a un MultiBinding
oggetto , creare una classe che implementa l'interfaccia IMultiValueConverter
e quindi implementare i Convert
metodi e 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;
}
}
}
Il Convert
metodo converte i valori di origine in un valore per la destinazione dell'associazione. Xamarin.Forms chiama questo metodo quando propaga i valori dalle associazioni di origine alla destinazione dell'associazione. Questo metodo accetta quattro argomenti:
values
, di tipoobject[]
, è una matrice di valori prodotti dalle associazioni di origine nell'oggettoMultiBinding
.targetType
, di tipoType
, è il tipo della proprietà di destinazione dell'associazione.parameter
, di tipoobject
, è il parametro del convertitore da usare.culture
, di tipoCultureInfo
, è le impostazioni cultura da usare nel convertitore.
Il Convert
metodo restituisce un oggetto object
che rappresenta un valore convertito. Questo metodo deve restituire:
BindableProperty.UnsetValue
per indicare che il convertitore non ha prodotto un valore e che l'associazione userà .FallbackValue
Binding.DoNothing
per indicare a Xamarin.Forms di non eseguire alcuna azione. Ad esempio, per indicare a Xamarin.Forms di non trasferire un valore alla destinazione di associazione o di non usare .FallbackValue
null
per indicare che il convertitore non può eseguire la conversione e che l'associazione userà .TargetNullValue
Importante
Oggetto MultiBinding
che riceve BindableProperty.UnsetValue
da un Convert
metodo deve definire la relativa FallbackValue
proprietà. Analogamente, un oggetto MultiBinding
che riceve null
da un Convert
metodo deve definirne la TargetNullValue
proprietà.
Il ConvertBack
metodo converte una destinazione di associazione nei valori di associazione di origine. Questo metodo accetta quattro argomenti:
value
, di tipoobject
, è il valore prodotto dalla destinazione di associazione.targetTypes
, di tipoType[]
, è la matrice di tipi in cui eseguire la conversione. La lunghezza della matrice indica il numero e i tipi di valori proposti per la restituzione da parte del metodo.parameter
, di tipoobject
, è il parametro del convertitore da usare.culture
, di tipoCultureInfo
, è le impostazioni cultura da usare nel convertitore.
Il ConvertBack
metodo restituisce una matrice di valori, di tipo object[]
, che sono stati convertiti dal valore di destinazione ai valori di origine. Questo metodo deve restituire:
BindableProperty.UnsetValue
in posizionei
per indicare che il convertitore non è in grado di fornire un valore per l'associazione di origine in corrispondenza dell'indicei
e che non deve essere impostato alcun valore su di esso.Binding.DoNothing
in posizionei
per indicare che non deve essere impostato alcun valore nell'associazione di origine in corrispondenza dell'indicei
.null
per indicare che il convertitore non può eseguire la conversione o che non supporta la conversione in questa direzione.
Utilizzare un oggetto IMultiValueConverter
Un IMultiValueConverter
oggetto viene utilizzato creando un'istanza in un dizionario risorse e quindi facendo riferimento a esso usando l'estensione StaticResource
di markup per impostare la MultiBinding.Converter
proprietà :
<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>
In questo esempio l'oggetto usa l'istanza AllTrueMultiConverter
di per impostare la CheckBox.IsChecked
proprietà su true
, a condizione che i tre Binding
oggetti restituiscono true
.MultiBinding
In caso contrario, la CheckBox.IsChecked
proprietà è impostata su false
.
Per impostazione predefinita, la CheckBox.IsChecked
proprietà usa un'associazione TwoWay
. Di conseguenza, il ConvertBack
metodo dell'istanza AllTrueMultiConverter
viene eseguito quando l'oggetto CheckBox
viene deselezionato dall'utente, che imposta i valori dell'associazione di origine sul valore della CheckBox.IsChecked
proprietà.
Il codice C# equivalente è illustrato di seguito:
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;
}
}
Stringhe di formato
Un MultiBinding
oggetto può formattare qualsiasi risultato di associazione multipla visualizzato come stringa, con la StringFormat
proprietà . Questa proprietà può essere impostata su una stringa di formattazione .NET standard, con segnaposto, che specifica come formattare il risultato dell'associazione multipla:
<Label>
<Label.Text>
<MultiBinding StringFormat="{}{0} {1} {2}">
<Binding Path="Employee1.Forename" />
<Binding Path="Employee1.MiddleName" />
<Binding Path="Employee1.Surname" />
</MultiBinding>
</Label.Text>
</Label>
In questo esempio la StringFormat
proprietà combina i tre valori associati in una singola stringa visualizzata da Label
.
Il codice C# equivalente è illustrato di seguito:
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
Il numero di parametri in un formato di stringa composita non può superare il numero di oggetti figlio Binding
in MultiBinding
.
Quando si impostano le Converter
proprietà eStringFormat
, il convertitore viene applicato prima al valore di dati e quindi viene applicato .StringFormat
Per altre informazioni sulla formattazione delle stringhe in Xamarin.Forms, vedere Formattazione di stringhe Xamarin.Forms.
Specificare i valori di fallback
I data binding possono essere resi più affidabili definendo i valori di fallback da usare se il processo di associazione ha esito negativo. Questa operazione può essere eseguita definendo facoltativamente le FallbackValue
proprietà e TargetNullValue
in un MultiBinding
oggetto .
Un MultiBinding
oggetto userà FallbackValue
quando il Convert
metodo di un'istanza IMultiValueConverter
restituisce BindableProperty.UnsetValue
, che indica che il convertitore non ha prodotto un valore. Un MultiBinding
oggetto userà TargetNullValue
quando il Convert
metodo di un'istanza IMultiValueConverter
restituisce null
, che indica che il convertitore non può eseguire la conversione.
Per altre informazioni sui fallback di binding, vedere Fallback di binding di Xamarin.Forms.
Annidare oggetti MultiBinding
MultiBinding
Gli oggetti possono essere annidati in modo che più MultiBinding
oggetti vengano valutati per restituire un valore tramite un'istanza IMultiValueConverter
di :
<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>
In questo esempio, l'oggetto MultiBinding
usa la relativa AnyTrueMultiConverter
istanza per impostare la CheckBox.IsChecked
proprietà su true
, a condizione che tutti gli Binding
oggetti dell'oggetto interno MultiBinding
restituiscono true
o che l'oggetto Binding
nell'oggetto esterno MultiBinding
restituisca true
. In caso contrario, la CheckBox.IsChecked
proprietà è impostata su false
.
Usare un'associazione RelativeSource in un multibinding
MultiBinding
gli oggetti supportano associazioni relative, che consentono di impostare l'origine dell'associazione in relazione alla posizione della destinazione dell'associazione:
<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>
Nota
Il Expander
controllo fa ora parte di Xamarin Community Toolkit.
In questo esempio viene usata la TemplatedParent
modalità di associazione relativa per eseguire il binding dall'interno di un modello di controllo all'istanza dell'oggetto di runtime a cui viene applicato il modello. L'oggetto Expander
, che è l'elemento radice di , ha il relativo BindingContext
set sull'istanza dell'oggetto ControlTemplate
runtime a cui viene applicato il modello. Pertanto, gli oggetti e i Expander
relativi elementi figlio risolvono le espressioni di associazione e Binding
gli oggetti rispetto alle proprietà dell'oggetto CardViewExpander
. MultiBinding
Usa l'istanza AllTrueMultiConverter
di per impostare la Expander.IsVisible
proprietà su a true
condizione che i due Binding
oggetti restituiscono true
. In caso contrario, la Expander.IsVisible
proprietà è impostata su false
.
Per altre informazioni sulle associazioni relative, vedere Associazioni relative di Xamarin.Forms. Per altre informazioni sui modelli di controllo, vedere Modelli di controllo Xamarin.Forms.