Udostępnij za pośrednictwem


Wielowiążniki zestawu narzędzi Xamarin.Forms

Powiązania wielowiążowe umożliwiają dołączanie kolekcji Binding obiektów do pojedynczej właściwości docelowej powiązania. Są one tworzone za pomocą MultiBinding klasy, która ocenia wszystkie jego Binding obiekty i zwraca pojedynczą wartość za pośrednictwem wystąpienia dostarczonego IMultiValueConverter przez aplikację. Ponadto ponownie zszacuje wszystkie jego Binding obiekty, MultiBinding gdy którykolwiek z powiązanych danych ulegnie zmianie.

Klasa MultiBinding definiuje następujące właściwości:

  • Bindings, typu IList<BindingBase>, który reprezentuje kolekcję Binding obiektów w ramach MultiBinding wystąpienia.
  • Converter, typu IMultiValueConverter, który reprezentuje konwerter do użycia w celu przekonwertowania wartości źródłowych na lub z wartości docelowej.
  • ConverterParameter, typu object, który reprezentuje opcjonalny parametr do przekazania do .Converter

Właściwość Bindings jest właściwością MultiBinding content klasy i dlatego nie musi być jawnie ustawiana z języka XAML.

Ponadto MultiBinding klasa dziedziczy następujące właściwości z BindingBase klasy:

  • FallbackValue, typu object, który reprezentuje wartość do użycia, gdy multi-binding nie może zwrócić wartości.
  • Mode, typu BindingMode, który wskazuje kierunek przepływu danych powiązania wielowiążkowego.
  • StringFormat, typu string, który określa sposób formatowania wyniku wielowiążkowego, jeśli jest wyświetlany jako ciąg.
  • TargetNullValue, typu object, który reprezentuje wartość używaną w obiekcie docelowym wen wartość źródła to null.

Element MultiBinding musi użyć elementu , IMultiValueConverter aby utworzyć wartość elementu docelowego powiązania na podstawie wartości powiązań w kolekcji Bindings . Na przykład Color wartości mogą być obliczane z czerwonych, niebieskich i zielonych wartości, które mogą być wartościami z tych samych lub różnych obiektów źródłowych powiązania. Gdy wartość zostanie przeniesiona z elementu docelowego do źródeł, wartość właściwości docelowej jest tłumaczona na zestaw wartości, które są przekazywane z powrotem do powiązań.

Ważne

Poszczególne powiązania w Bindings kolekcji mogą mieć własne konwertery wartości.

Wartość Mode właściwości określa funkcjonalność MultiBindingelementu i jest używana jako tryb powiązania dla wszystkich powiązań w kolekcji, chyba że pojedyncze powiązanie zastępuje właściwość . Jeśli na przykład Mode właściwość obiektu MultiBinding jest ustawiona na TwoWaywartość , wszystkie powiązania w kolekcji są traktowane, TwoWay chyba że jawnie ustawisz inną Mode wartość na jednym z powiązań.

Definiowanie elementu IMultiValueConverter

Interfejs IMultiValueConverter umożliwia zastosowanie logiki niestandardowej do elementu MultiBinding. Aby skojarzyć konwerter z klasą MultiBinding, utwórz klasę, która implementuje IMultiValueConverter interfejs, a następnie zaimplementuj Convert metody i 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;
        }
    }
}

Metoda Convert konwertuje wartości źródłowe na wartość elementu docelowego powiązania. Platforma Xamarin.Forms wywołuje tę metodę, gdy propaguje wartości z powiązań źródłowych do obiektu docelowego powiązania powiązania. Ta metoda akceptuje cztery argumenty:

  • values, typu object[], to tablica wartości, które tworzy powiązania źródłowe.MultiBinding
  • targetType, typu , jest typem Typewłaściwości docelowej powiązania.
  • parameter, typu object, jest parametrem konwertera do użycia.
  • culture, typu CultureInfo, to kultura, która ma być używana w konwerterze.

Metoda Convert zwraca wartość object reprezentującą przekonwertowaną wartość. Ta metoda powinna zwrócić:

  • BindableProperty.UnsetValue aby wskazać, że konwerter nie wygenerował wartości i że powiązanie będzie używać FallbackValue.
  • Binding.DoNothing w celu poinstruowania platformy Xamarin.Forms, aby nie wykonywał żadnej akcji. Aby na przykład poinstruować platformę Xamarin.Forms, aby nie transferował wartości do obiektu docelowego powiązania, lub nie używać elementu FallbackValue.
  • null aby wskazać, że konwerter nie może wykonać konwersji, a powiązanie będzie używać TargetNullValue.

Ważne

Obiekt MultiBinding odbierający BindableProperty.UnsetValue Convert z metody musi definiować jej FallbackValue właściwość. Podobnie element odbierający MultiBinding null z Convert metody musi zdefiniować jego TargetNullValue propety.

Metoda ConvertBack konwertuje element docelowy powiązania na wartości powiązania źródłowego. Ta metoda akceptuje cztery argumenty:

  • value, typu object, to wartość, którą generuje obiekt docelowy powiązania.
  • targetTypes, typu Type[], to tablica typów do konwersji na. Długość tablicy wskazuje liczbę i typy wartości sugerowanych dla metody do zwrócenia.
  • parameter, typu object, jest parametrem konwertera do użycia.
  • culture, typu CultureInfo, to kultura, która ma być używana w konwerterze.

Metoda ConvertBack zwraca tablicę wartości typu object[], które zostały przekonwertowane z wartości docelowej z powrotem na wartości źródłowe. Ta metoda powinna zwrócić:

  • BindableProperty.UnsetValue w pozycji i , aby wskazać, że konwerter nie może podać wartości powiązania źródłowego w indeksie i, i że nie ma na nim ustawionej żadnej wartości.
  • Binding.DoNothing w pozycji i , aby wskazać, że żadna wartość nie ma być ustawiona na powiązanie źródłowe w indeksie i.
  • null aby wskazać, że konwerter nie może wykonać konwersji lub że nie obsługuje konwersji w tym kierunku.

Korzystanie z elementu IMultiValueConverter

Element A IMultiValueConverter jest używany przez utworzenie wystąpienia go w słowniku zasobów, a następnie odwoływanie się do niego przy użyciu StaticResource rozszerzenia znaczników w celu ustawienia MultiBinding.Converter właściwości:

<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>    

W tym przykładzie obiekt używa AllTrueMultiConverter wystąpienia do ustawienia CheckBox.IsChecked właściwości na true, pod warunkiem, że trzy Binding obiekty oceniają wartość true.MultiBinding W przeciwnym razie właściwość jest ustawiona CheckBox.IsChecked na false.

Domyślnie CheckBox.IsChecked właściwość używa TwoWay powiązania. ConvertBack W związku z tym metoda AllTrueMultiConverter wystąpienia jest wykonywana, gdy CheckBox obiekt jest niezaznaczone przez użytkownika, co ustawia wartości powiązania źródłowego CheckBox.IsChecked na wartość właściwości.

Równoważny kod języka C# jest pokazany poniżej:

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;
    }
}

Formatuj ciągi

Obiekt MultiBinding może formatować dowolny wynik powiązania wielowiążkowego, który jest wyświetlany jako ciąg z właściwością StringFormat . Tę właściwość można ustawić na standardowy ciąg formatowania platformy .NET z symbolami zastępczymi, który określa sposób formatowania wyniku wielowiążkowego:

<Label>
    <Label.Text>
        <MultiBinding StringFormat="{}{0} {1} {2}">
            <Binding Path="Employee1.Forename" />
            <Binding Path="Employee1.MiddleName" />
            <Binding Path="Employee1.Surname" />
        </MultiBinding>
    </Label.Text>
</Label>

W tym przykładzie StringFormat właściwość łączy trzy powiązane wartości w jeden ciąg wyświetlany przez Labelelement .

Równoważny kod języka C# jest pokazany poniżej:

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}"
});

Ważne

Liczba parametrów w formacie ciągu złożonego nie może przekraczać liczby obiektów podrzędnych Binding w obiekcie MultiBinding.

Podczas ustawiania Converter właściwości i StringFormat konwerter jest najpierw stosowany do wartości danych, a następnie StringFormat jest stosowany.

Aby uzyskać więcej informacji na temat formatowania ciągów na platformie Xamarin.Forms, zobacz Formatowanie ciągów platformy Xamarin.Forms.

Podaj wartości rezerwowe

Powiązania danych mogą być bardziej niezawodne, definiując wartości rezerwowe do użycia, jeśli proces powiązania zakończy się niepowodzeniem. Można to zrobić, definiując FallbackValue opcjonalnie właściwości i TargetNullValue dla MultiBinding obiektu.

Funkcja MultiBinding będzie używać jej FallbackValue , gdy Convert metoda IMultiValueConverter wystąpienia zwraca BindableProperty.UnsetValuewartość , która wskazuje, że konwerter nie wygenerował wartości. Obiekt MultiBinding będzie używać jejTargetNullValue, gdy Convert metoda wystąpienia zwraca nullwartość IMultiValueConverter , która wskazuje, że konwerter nie może wykonać konwersji.

Aby uzyskać więcej informacji na temat rezerwowych powiązań, zobacz Rezerwowe powiązania zestawu narzędzi Xamarin.Forms.

Zagnieżdżanie obiektów MultiBinding

MultiBinding obiekty można zagnieżdżać, aby wiele MultiBinding obiektów było ocenianych w celu zwrócenia wartości za pośrednictwem IMultiValueConverter wystąpienia:

<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>

W tym przykładzie MultiBinding obiekt używa jego AnyTrueMultiConverter wystąpienia, aby ustawić CheckBox.IsChecked właściwość na true, pod warunkiem, że wszystkie Binding obiekty w obiekcie wewnętrznym MultiBinding mają wartość true, lub pod warunkiem, że Binding obiekt w obiekcie zewnętrznym MultiBinding daje wartość true. W przeciwnym razie właściwość jest ustawiona CheckBox.IsChecked na false.

Używanie powiązania RelativeSource w funkcji MultiBinding

MultiBinding obiekty obsługują powiązania względne, które zapewniają możliwość ustawiania źródła powiązania względem położenia obiektu docelowego powiązania:

<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>

Uwaga

Kontrolka Expander jest teraz częścią zestawu narzędzi Xamarin Community Toolkit.

W tym przykładzie TemplatedParent tryb powiązania względnego jest używany do powiązania z szablonu kontrolki z wystąpieniem obiektu środowiska uruchomieniowego, do którego zastosowano szablon. Element Expander, który jest elementem ControlTemplategłównym obiektu , ma ustawiony BindingContext na wystąpienie obiektu środowiska uruchomieniowego, do którego jest stosowany szablon. Expander W związku z tym obiekty i jego elementy podrzędne rozpoznają swoje wyrażenia powiązania i Binding obiekty względem właściwości CardViewExpander obiektu. Używa MultiBinding wystąpienia, aby ustawić Expander.IsVisible właściwość w celu true zapewnienia, że dwa Binding obiekty oceniają wartość true.AllTrueMultiConverter W przeciwnym razie właściwość jest ustawiona Expander.IsVisible na false.

Aby uzyskać więcej informacji na temat powiązań względnych, zobacz Powiązania względne zestawu narzędzi Xamarin.Forms. Aby uzyskać więcej informacji na temat szablonów kontrolek, zobacz Szablony kontrolek zestawu narzędzi Xamarin.Forms.