Sdílet prostřednictvím


Více vazeb Xamarin.Forms

Více vazeb umožňuje připojit kolekci Binding objektů k jedné cílové vlastnosti vazby. Vytvoří se s MultiBinding třídou, která vyhodnocuje všechny její Binding objekty, a vrátí jednu hodnotu prostřednictvím IMultiValueConverter instance poskytované vaší aplikací. Kromě toho znovu vyhodnocuje všechny jeho Binding objekty, MultiBinding když se změní některá z vázaných dat.

Třída MultiBinding definuje následující vlastnosti:

  • Bindings, typu IList<BindingBase>, který představuje kolekci Binding objektů v instanci MultiBinding .
  • Converter, typu IMultiValueConverter, který představuje převaděč, který se má použít k převodu zdrojových hodnot na cílovou hodnotu nebo z ní.
  • ConverterParameter, typu object, který představuje volitelný parametr, který se má předat .Converter

Vlastnost Bindings je vlastnost MultiBinding obsahu třídy, a proto není nutné explicitně nastavit z XAML.

Kromě toho MultiBinding třída dědí následující vlastnosti z BindingBase třídy:

  • FallbackValue, typu object, který představuje hodnotu, která se má použít, když více vazby nemůže vrátit hodnotu.
  • Mode, typu BindingMode, který označuje směr toku dat více vazeb.
  • StringFormat, typu string, který určuje, jak formátovat výsledek více vazeb, pokud se zobrazí jako řetězec.
  • TargetNullValue, typu object, který představuje hodnotu, která se používá v cílovém wen hodnotu zdroje je null.

Musí MultiBinding použít IMultiValueConverter hodnotu pro cíl vazby na základě hodnoty vazeb v kolekci Bindings . Například je možné vypočítat červenou, modrou a zelenou Color hodnotu, což mohou být hodnoty ze stejných nebo různých zdrojových objektů vazby. Když se hodnota přesune z cíle na zdroje, cílová hodnota vlastnosti se přeloží na sadu hodnot, které se předávají zpět do vazeb.

Důležité

Jednotlivé vazby v kolekci Bindings mohou mít své vlastní převaděče hodnot.

Hodnota Mode vlastnosti určuje funkce MultiBindinga je použita jako režim vazby pro všechny vazby v kolekci, pokud jednotlivé vazby nepřepíše vlastnost. Pokud je například vlastnost objektu Mode MultiBinding nastavena na TwoWay, jsou všechny vazby v kolekci považovány za TwoWay předpokladu, že explicitně nenastavíte jinou Mode hodnotu na některé z vazeb.

Definování IMultiValueConverter

Rozhraní IMultiValueConverter umožňuje použití vlastní logiky na objekt .MultiBinding Chcete-li přidružit převaděč k , MultiBindingvytvořte třídu, která implementuje IMultiValueConverter rozhraní, a pak implementujte Convert a ConvertBack metody:

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 převede zdrojové hodnoty na hodnotu cíle vazby. Xamarin.Forms volá tuto metodu při šíření hodnot ze zdrojových vazeb do cíle vazby. Tato metoda přijímá čtyři argumenty:

  • values, typu object[], je pole hodnot, které zdrojové vazby v MultiBinding generovaných.
  • targetType, typu Type, je typ vazby cílové vlastnosti.
  • parameter, typu object, je parametr převaděče, který se má použít.
  • culture, typu CultureInfo, je jazyková verze, která se má použít v převaděči.

Metoda Convert vrátí object hodnotu, která představuje převedenou hodnotu. Tato metoda by měla vrátit:

  • BindableProperty.UnsetValue k označení, že převaděč nevytvářel hodnotu a že vazba bude používat FallbackValue.
  • Binding.DoNothing pokyn Xamarin.Forms, aby neprovázal žádnou akci. Chcete-li například dát Xamarin.Forms pokyn, aby nepřenesl hodnotu do cíle vazby nebo aby nepoužít FallbackValue.
  • null k označení, že převaděč nemůže provést převod a že vazba bude používat TargetNullValue.

Důležité

Objekt MultiBinding , který přijímá BindableProperty.UnsetValue z Convert metody, musí definovat jeho FallbackValue vlastnost. Podobně musí objekt, MultiBinding který přijímá null z Convert metody definovat jeho TargetNullValue propety.

Metoda ConvertBack převede cíl vazby na hodnoty zdrojové vazby. Tato metoda přijímá čtyři argumenty:

  • value, typu objectje hodnota, kterou cíl vazby vytvoří.
  • targetTypes, typu Type[], je pole typů, na které se má převést. Délka pole označuje počet a typy hodnot, které jsou navrženy pro vrácení metody.
  • parameter, typu object, je parametr převaděče, který se má použít.
  • culture, typu CultureInfo, je jazyková verze, která se má použít v převaděči.

Metoda ConvertBack vrátí pole hodnot typu object[], které byly převedeny z cílové hodnoty zpět na zdrojové hodnoty. Tato metoda by měla vrátit:

  • BindableProperty.UnsetValue na pozici i , která má naznačovat, že převaděč nemůže poskytnout hodnotu pro zdrojovou vazbu v indexu ia že v něm není nastavena žádná hodnota.
  • Binding.DoNothing na pozici i označující, že u zdrojové vazby v indexu inení nastavena žádná hodnota .
  • null chcete-li označit, že převaděč nemůže provést převod nebo že nepodporuje převod v tomto směru.

Využití IMultiValueConverter

A IMultiValueConverter se spotřebovává vytvořením instance ve slovníku prostředků a následným odkazováním na tuto vlastnost pomocí StaticResource rozšíření MultiBinding.Converter značek:

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

V tomto příkladu objekt používá instanci k nastavení CheckBox.IsChecked vlastnosti true, za předpokladu, že tři Binding objekty jsou vyhodnoceny jako true.MultiBinding AllTrueMultiConverter V opačném případě je vlastnost nastavena CheckBox.IsChecked na falsehodnotu .

Ve výchozím nastavení vlastnost CheckBox.IsChecked používá TwoWay vazbu. Proto je metoda AllTrueMultiConverter instance spuštěna v ConvertBack případěCheckBox, že je nezaškrtnuto uživatelem, který nastaví hodnoty zdrojové vazby na hodnotu CheckBox.IsChecked vlastnosti.

Ekvivalentní kód jazyka C# je uvedený níže:

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

Formátování řetězců

A MultiBinding může formátovat libovolný výsledek s více vazbami, který se zobrazí jako řetězec s StringFormat vlastností. Tuto vlastnost lze nastavit na standardní formátovací řetězec .NET se zástupnými symboly, který určuje, jak formátovat výsledek více vazeb:

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

V tomto příkladu StringFormat vlastnost kombinuje tři vázané hodnoty do jednoho řetězce, který je zobrazen v objektu Label.

Ekvivalentní kód jazyka C# je uvedený níže:

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

Důležité

Počet parametrů ve složeného řetězcovém formátu nesmí překročit počet podřízených Binding objektů v objektu MultiBinding.

Při nastavování Converter a StringFormat vlastností se převaděč nejprve použije na hodnotu dat a pak se StringFormat použije.

Další informace o formátování řetězců v Xamarin.Forms naleznete v tématu Xamarin.Forms String Formatting.

Zadání záložních hodnot

Datové vazby mohou být robustnější definováním záložních hodnot, které se mají použít, pokud proces vazby selže. Toho lze dosáhnout volitelným definováním FallbackValue a TargetNullValue vlastnostmi objektu MultiBinding .

A MultiBinding použije ji FallbackValue , když Convert metoda IMultiValueConverter instance vrátí BindableProperty.UnsetValue, což označuje, že převaděč nevytvářel hodnotu. A MultiBinding použije ji TargetNullValue , když Convert metoda IMultiValueConverter instance vrátí null, což znamená, že převaděč nemůže provést převod.

Další informace o záložních vazbách najdete v tématu Náhradní vazby Xamarin.Forms.

Vnoření objektů MultiBinding

MultiBinding Objekty lze vnořit tak, aby se vyhodnocovaly více MultiBinding objektů, aby se vrátila hodnota prostřednictvím IMultiValueConverter instance:

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

V tomto příkladu MultiBinding objekt používá svou AnyTrueMultiConverter instanci k nastavení CheckBox.IsChecked vlastnosti true, za předpokladu, že všechny Binding objekty ve vnitřním MultiBinding objektu vyhodnotí , truenebo za předpokladu, že Binding objekt ve vnějším MultiBinding objektu je vyhodnocen jako true. V opačném případě je vlastnost nastavena CheckBox.IsChecked na falsehodnotu .

Použití vazby RelativeSource v multibindingu

MultiBinding objekty podporují relativní vazby, které poskytují možnost nastavit zdroj vazby vzhledem k pozici cíle vazby:

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

Poznámka:

Ovládací Expander prvek je teď součástí sady nástrojů Xamarin Community Toolkit.

V tomto příkladu TemplatedParent se relativní režim vazby používá k vytvoření vazby z řídicí šablony na instanci objektu runtime, na kterou je šablona použita. , Expandercož je kořenový prvek ControlTemplate, má jeho BindingContext nastavena na runtime objekt instance, na kterou je šablona použita. Expander Proto a jeho podřízené objekty přeloží svá vazbové výrazy a Binding objekty proti vlastnostem objektuCardViewExpander. Používá MultiBinding AllTrueMultiConverter instanci k nastavení vlastnosti true za předpokladuExpander.IsVisible, že dva Binding objekty jsou vyhodnoceny jako true. V opačném případě je vlastnost nastavena Expander.IsVisible na falsehodnotu .

Další informace o relativních vazbách najdete v tématu Relativní vazby Xamarin.Forms. Další informace o šablonách ovládacích prvků naleznete v tématu Šablony ovládacích prvků Xamarin.Forms.