Multi-binding di Xamarin.Forms

Download Sample Scaricare l'esempio

Le associazioni multipla consentono di associare una raccolta di Binding oggetti a una singola proprietà di destinazione dell'associazione. Vengono creati con la classe , che valuta tutti i relativi oggetti e restituisce un singolo valore tramite un'istanza MultiBindingBinding fornita IMultiValueConverter dall'applicazione. Inoltre, MultiBinding rivaluta tutti i relativi Binding oggetti quando uno dei dati associati viene modificato.

La MultiBinding classe definisce le proprietà seguenti:

  • Bindings, di tipo IList<BindingBase> , che rappresenta la raccolta di oggetti Binding all'interno MultiBinding dell'istanza di .
  • Converter, di tipo IMultiValueConverter , che rappresenta il convertitore da utilizzare per convertire i valori di origine in o dal valore di destinazione.
  • ConverterParameter, di tipo object , che rappresenta un parametro facoltativo da passare a Converter .

La proprietà è la proprietà content della classe e pertanto non deve essere impostata in modo BindingsMultiBinding esplicito da XAML.

Inoltre, la MultiBinding classe eredita le proprietà seguenti dalla classe BindingBase :

  • FallbackValue, di tipo object , che rappresenta il valore da utilizzare quando la multi-associazione non è in grado di restituire un valore.
  • Mode, di tipo BindingMode , che indica la direzione del flusso di dati del multi-binding.
  • StringFormat, di tipo , che specifica come formattare il risultato del multi-binding se viene string visualizzato come stringa.
  • TargetNullValue, di tipo , che rappresenta il valore utilizzato nell'oggetto di destinazione. Il object valore dell'origine è null .

Un MultiBinding oggetto deve utilizzare un oggetto per produrre un valore per la destinazione dell'associazione, in base al IMultiValueConverter valore delle associazioni nella Bindings raccolta. Ad esempio, un oggetto può essere calcolato da valori rosso, blu e verde, che possono essere valori dello stesso oggetto origine di associazione o di Color oggetti diversi. Quando un valore viene spostato dalla destinazione alle origini, il valore della proprietà di destinazione viene convertito in un set di valori che vengono nuovamente immessi nelle associazioni.

Importante

Le singole associazioni nella Bindings raccolta possono avere i propri convertitori di valori.

Il valore della proprietà determina la funzionalità di e viene utilizzato come modalità di associazione per tutte le associazioni nella raccolta, a meno che una singola associazione non ese sostituisca ModeMultiBinding la proprietà . Ad esempio, se la proprietà di un oggetto è impostata su , vengono considerate tutte le associazioni nella raccolta, a meno che non si imposta in modo esplicito un valore diverso ModeMultiBinding in una delle TwoWayTwoWayMode associazioni.

Definire un oggetto IMultiValueConverter

IMultiValueConverterL'interfaccia consente l'applicazione della logica personalizzata a un oggetto MultiBinding . Per associare un convertitore a MultiBinding un oggetto , creare una classe che implementa l'interfaccia e quindi IMultiValueConverter implementare i metodi e ConvertConvertBack :

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 del binding. Questo metodo accetta quattro argomenti:

  • values, di tipo object[] , è una matrice di valori prodotti dall'associazione di origine in MultiBinding .
  • targetType, di tipo Type , è il tipo della proprietà di destinazione dell'associazione.
  • parameter, di tipo object , è il parametro del convertitore da usare.
  • culture, di tipo CultureInfo , sono le impostazioni cultura da utilizzare nel convertitore.

Il Convert metodo restituisce un oggetto che rappresenta un valore object convertito. Questo metodo deve restituire:

  • BindableProperty.UnsetValue per indicare che il convertitore non ha prodotto un valore e che l'associazione utilizzerà 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 dell'associazione o di non usare FallbackValue .
  • null per indicare che il convertitore non può eseguire la conversione e che l'associazione utilizzerà TargetNullValue .

Importante

Un MultiBinding oggetto che riceve da un metodo deve definire la relativa proprietà BindableProperty.UnsetValueConvertFallbackValue . Analogamente, un MultiBinding oggetto che riceve da un metodo deve definire la relativa proprietà nullConvertTargetNullValue .

Il ConvertBack metodo converte una destinazione di associazione nei valori di associazione di origine. Questo metodo accetta quattro argomenti:

  • value, di tipo object , è il valore prodotto dalla destinazione dell'associazione.
  • targetTypes, di tipo Type[] , è 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 tipo object , è il parametro del convertitore da usare.
  • culture, di tipo CultureInfo , sono le impostazioni cultura da utilizzare nel convertitore.

Il metodo restituisce una matrice di valori, di tipo , che sono stati convertiti dal valore ConvertBack di destinazione ai valori di object[] origine. Questo metodo deve restituire:

  • BindableProperty.UnsetValue nella posizione per indicare che il convertitore non è in grado di fornire un valore per l'associazione di origine in corrispondenza dell'indice e che non deve i essere impostato alcun valore su di i esso.
  • Binding.DoNothing in corrispondenza i della posizione per indicare che non è necessario impostare alcun valore nell'associazione di origine in corrispondenza dell'indice i .
  • 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 oggetto viene utilizzato creando un'istanza di in un dizionario risorse e quindi facendo riferimento a esso usando l'estensione IMultiValueConverter di markup per impostare la proprietà StaticResourceMultiBinding.Converter :

<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 MultiBinding l'oggetto usa l'istanza di per impostare la proprietà su , a condizione che i AllTrueMultiConverter tre oggetti CheckBox.IsCheckedtrueBinding restituiranno true . In caso contrario, CheckBox.IsChecked la proprietà è impostata su false .

Per impostazione predefinita, CheckBox.IsChecked la proprietà usa TwoWay un'associazione . Di conseguenza, il metodo dell'istanza viene eseguito quando l'oggetto viene deselezionato dall'utente, che imposta i valori dell'associazione di ConvertBack origine sul valore della proprietà AllTrueMultiConverterCheckBoxCheckBox.IsChecked .

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 oggetto può formattare qualsiasi risultato a più associazioni visualizzato MultiBinding 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 proprietà combina i tre valori associati in una singola stringa StringFormat 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 stringa composito non può superare il numero di oggetti Binding figlio in MultiBinding .

Quando si impostano le proprietà e , il convertitore viene applicato prima al valore ConverterStringFormat dei dati, quindi viene applicato StringFormat .

Per altre informazioni sulla formattazione delle stringhe in Xamarin.Forms, vedere Formattazione di stringhe in Xamarin.Forms.

Specificare i valori di fallback

I data binding possono essere resi più affidabili definendo i valori di fallback da usare in caso di errore del processo di associazione. Questa operazione può essere eseguita definendo facoltativamente le FallbackValue proprietà e in un oggetto TargetNullValueMultiBinding .

Un oggetto utilizzerà quando il metodo di un'istanza restituisce , che indica che il MultiBindingFallbackValueConvertIMultiValueConverterBindableProperty.UnsetValue convertitore non ha prodotto un valore. Un oggetto utilizzerà quando il metodo di un'istanza restituisce , che indica che il convertitore non MultiBinding può eseguire la TargetNullValueConvertIMultiValueConverternull conversione.

Per altre informazioni sui fallback di associazione, vedere Fallback di binding di Xamarin.Forms.

Annidare oggetti MultiBinding

MultiBinding Gli oggetti possono essere annidati in modo MultiBinding che più oggetti siano valutati per restituire un valore tramite un'istanza di IMultiValueConverter :

<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 usa la relativa istanza di per impostare la proprietà su , purché tutti gli oggetti nell'oggetto interno restituiranno o purché l'oggetto nell'oggetto esterno MultiBindingAnyTrueMultiConverterCheckBox.IsCheckedtrueBindingMultiBindingtrueBindingMultiBinding restituirà true . In caso contrario, CheckBox.IsChecked la proprietà è impostata su false .

Usare un'associazione RelativeSource in un oggetto MultiBinding

MultiBinding Gli oggetti supportano associazioni relative, che consentono di impostare l'origine del binding rispetto 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 del controllo Xamarin Community Toolkit.

In questo esempio, la modalità di associazione relativa viene usata per eseguire l'associazione dall'interno di un modello di controllo all'istanza dell'oggetto di runtime a cui TemplatedParent è applicato il modello. , che è l'elemento radice di , ha impostato sull'istanza Expander dell'oggetto di runtime a cui viene applicato il ControlTemplateBindingContext modello. Pertanto, e i relativi elementi figlio risolvono le espressioni di associazione e gli oggetti Expander in base alle proprietà BindingCardViewExpander dell'oggetto. usa MultiBindingAllTrueMultiConverter l'istanza di per impostare la proprietà su , a condizione che i due oggetti Expander.IsVisibletrueBinding restituiranno true . In caso contrario, Expander.IsVisible la 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.