Aracılığıyla paylaş


Xamarin.Forms Çoklu Bağlamaları

Çoklu bağlamalar, tek bir bağlama hedef özelliğine nesne koleksiyonu Binding ekleme olanağı sağlar. Tüm nesnelerini değerlendiren Binding ve uygulamanız tarafından sağlanan bir IMultiValueConverter örnek aracılığıyla tek bir değer döndüren sınıfıyla MultiBinding oluşturulur. Buna ek olarak, MultiBinding ilişkili verilerden herhangi biri değiştiğinde tüm Binding nesnelerini yeniden değerlendirir.

MultiBinding sınıfı aşağıdaki özellikleri tanımlar:

  • Bindings, türündeki IList<BindingBase>örnek içindeki MultiBinding nesne koleksiyonunu Binding temsil eder.
  • Converter, türündeki IMultiValueConverterkaynak değerleri hedef değere veya hedef değerden dönüştürmek için kullanılacak dönüştürücüsü temsil eder.
  • ConverterParameter, türüne objectgöre, öğesine geçirebileceğiniz isteğe bağlı bir parametreyi Convertertemsil eder.

Bindings özelliği sınıfının içerik özelliğidir MultiBinding ve bu nedenle açıkça XAML'den ayarlanması gerekmez.

Ayrıca, MultiBinding sınıfı aşağıdaki özellikleri sınıfından BindingBase devralır:

  • FallbackValue, türündedir objectve çoklu bağlama bir değer döndüremediğinde kullanılacak değeri temsil eder.
  • Mode, türündedir BindingModeve birden çok bağlamanın veri akışının yönünü gösterir.
  • StringFormat, türündedir stringve bir dize olarak görüntülenirse çoklu bağlama sonucunun nasıl biçimlendirleneceğini belirtir.
  • TargetNullValue, hedef wen'de kullanılan değeri temsil eden türünde objectkaynağın değeridir null.

AMultiBinding, koleksiyondaki bağlamaların Bindings değerine bağlı olarak bağlama hedefi için bir değer üretmek için bir kullanmalıdırIMultiValueConverter. Örneğin, bir Color değeri aynı veya farklı bağlama kaynak nesnelerinden gelen değerler olabilecek kırmızı, mavi ve yeşil değerlerden hesaplanabilir. Bir değer hedeften kaynaklara geçtiğinde, hedef özellik değeri bağlamalara geri beslenen bir değer kümesine çevrilir.

Önemli

Koleksiyondaki Bindings tek tek bağlamaların kendi değer dönüştürücüleri olabilir.

özelliğinin Mode değeri, işlevini MultiBindingbelirler ve tek bir bağlama özelliği geçersiz kılmadığı sürece koleksiyondaki tüm bağlamalar için bağlama modu olarak kullanılır. Örneğin, bir nesnedeki Mode özelliği olarak TwoWayayarlanırsa, bağlamalardan birinde açıkça farklı Mode bir değer ayarlamadığınız sürece koleksiyondaki tüm bağlamalar dikkate alınırTwoWay.MultiBinding

IMultiValueConverter Tanımlama

Arabirimi, IMultiValueConverter özel mantığın uygulamasına MultiBindingolanak tanır. Bir dönüştürücü ile MultiBindingilişkilendirmek için arabirimini uygulayan IMultiValueConverter bir sınıf oluşturun ve ardından ve ConvertBack yöntemlerini uygulayınConvert:

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

yöntemi, Convert kaynak değerleri bağlama hedefi için bir değere dönüştürür. Xamarin.Forms, kaynak bağlamalardan bağlama hedefine değer yaydığında bu yöntemi çağırır. Bu yöntem dört bağımsız değişken kabul eder:

  • values, türündeki object[], kaynağın MultiBinding ürettiği bir değer dizisidir.
  • targetType, türündeki Type, bağlama hedef özelliğinin türüdür.
  • parameter, türünde object, kullanılacak dönüştürücü parametresidir.
  • culture, türünde CultureInfo, dönüştürücüde kullanılacak kültürdür.

yöntemi, Convert dönüştürülen bir değeri temsil eden bir döndürür object . Bu yöntem şunu döndürmelidir:

  • BindableProperty.UnsetValue dönüştürücüsunun bir değer üretmediğini ve bağlamanın öğesini kullanacağını belirtmek için FallbackValue.
  • Binding.DoNothing Xamarin.Forms'a herhangi bir eylem gerçekleştirmemesi için talimat verir. Örneğin, Xamarin.Forms'a bağlama hedefine bir değer aktarmamasını veya kullanmamasını FallbackValuebildirmek için.
  • null dönüştürücüsunun dönüştürmeyi gerçekleştiremediğini ve bağlamanın öğesini kullanacağını belirtmek için TargetNullValue.

Önemli

Bir MultiBinding yöntemden alan BindableProperty.UnsetValue özelliğini Convert tanımlamalıdır FallbackValue . Benzer şekilde, bir MultiBinding yöntemden alan null bir Convert öğesinin de kendi parçacığını TargetNullValue tanımlaması gerekir.

yöntemi, ConvertBack bağlama hedefini kaynak bağlama değerlerine dönüştürür. Bu yöntem dört bağımsız değişken kabul eder:

  • value, türündeki objectbağlama hedefinin ürettiği değerdir.
  • targetTypes, türündeki Type[], dönüştürülecek tür dizisidir. Dizi uzunluğu, yöntemin döndürmesi için önerilen değer sayısını ve türlerini gösterir.
  • parameter, türünde object, kullanılacak dönüştürücü parametresidir.
  • culture, türünde CultureInfo, dönüştürücüde kullanılacak kültürdür.

ConvertBack yöntemi, hedef değerden kaynak değerlere geri dönüştürülen türünde object[]bir değer dizisi döndürür. Bu yöntem şunu döndürmelidir:

  • BindableProperty.UnsetValue konumunda i , dönüştürücüsü dizinde ikaynak bağlama için bir değer sağlayamıyor ve üzerinde ayarlanacak bir değer yok.
  • Binding.DoNothing konumunda i olduğundan, dizindeki ikaynak bağlamada hiçbir değer ayarlanmayacağını belirtir.
  • null çeviricinin dönüştürmeyi gerçekleştiremediğini veya bu yönde dönüştürmeyi desteklemediğini belirtmek için.

IMultiValueConverter kullanma

bir IMultiValueConverter kaynak sözlüğünde örneği oluşturarak ve ardından özelliği ayarlamak MultiBinding.Converter için işaretleme uzantısını StaticResource kullanarak başvurarak kullanılır:

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

Bu örnekte nesnesi, MultiBinding üç Binding nesnenin AllTrueMultiConverter değerlendirmesi truekoşuluyla özelliğini trueolarak ayarlamak CheckBox.IsChecked için örneğini kullanır. Aksi takdirde özelliği CheckBox.IsChecked olarak falseayarlanır.

Varsayılan olarak özelliği CheckBox.IsChecked bir TwoWay bağlama kullanır. Bu nedenle, ConvertBack örneğin yöntemiAllTrueMultiConverter, kaynak bağlama değerlerini özelliğin değerine CheckBox.IsChecked ayarlayan kullanıcı tarafından işareti kaldırıldığında CheckBox yürütülür.

Eşdeğer C# kodu aşağıda gösterilmiştir:

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

Dizeleri biçimlendirme

, MultiBinding dize olarak görüntülenen herhangi bir çok bağlama sonucunu özelliğiyle StringFormat biçimlendirebilir. Bu özellik, çoklu bağlama sonucunun nasıl biçimlendirildiğini belirten yer tutucularla standart bir .NET biçimlendirme dizesine ayarlanabilir:

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

Bu örnekte özelliği, StringFormat üç ilişkili değeri tarafından görüntülenen tek bir dizede Labelbirleştirir.

Eşdeğer C# kodu aşağıda gösterilmiştir:

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

Önemli

Bileşik dize biçimindeki parametre sayısı içindeki MultiBindingalt Binding nesne sayısını aşamaz.

ve StringFormat özelliklerini ayarlarkenConverter, dönüştürücü önce veri değerine uygulanır ve ardından StringFormat uygulanır.

Xamarin.Forms'daki dize biçimlendirmesi hakkında daha fazla bilgi için bkz . Xamarin.Forms Dize Biçimlendirmesi.

Geri dönüş değerleri sağlama

Bağlama işlemi başarısız olursa kullanılacak geri dönüş değerleri tanımlanarak veri bağlamaları daha sağlam hale getirilebilir. Bu, isteğe bağlı olarak ve özelliklerini bir MultiBinding nesne üzerinde tanımlayarak FallbackValue TargetNullValue gerçekleştirilebilir.

AMultiBinding, bir IMultiValueConverter örneğin yöntemi döndürdüğünde Convert BindableProperty.UnsetValuedeğerini FallbackValue kullanır ve bu da dönüştürücüde bir değer üretilmediğini gösterir. AMultiBinding, bir IMultiValueConverter örneğin yöntemi döndürdüğünde Convert nullbunu TargetNullValue kullanır. Bu, dönüştürücüsü dönüştürmeyi gerçekleştiremediğini gösterir.

Geri dönüşleri bağlama hakkında daha fazla bilgi için bkz . Xamarin.Forms Bağlama Geri Dönüşleri.

MultiBinding nesnelerini iç içe yerleştirme

MultiBinding nesneleri iç içe yerleştirilebilir, böylece birden çok MultiBinding nesne bir örnek aracılığıyla IMultiValueConverter bir değer döndürecek şekilde değerlendirilir:

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

Bu örnekte nesnesi, MultiBindingMultiBinding nesnedeki tüm Binding nesnelerin değerlendirmesi veya dış MultiBinding nesnedeki nesnenin olarak değerlendirmesi truekoşuluyla Binding özelliğini trueolarak ayarlamak CheckBox.IsChecked için trueörneğini kullanırAnyTrueMultiConverter. Aksi takdirde özelliği CheckBox.IsChecked olarak falseayarlanır.

MultiBinding içinde RelativeSource bağlaması kullanma

MultiBinding nesneleri, bağlama kaynağını bağlama hedefinin konumuna göre ayarlama olanağı sağlayan göreli bağlamaları destekler:

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

Not

Denetim Expander artık Xamarin Topluluk Araç Seti'nin bir parçasıdır.

Bu örnekte göreli bağlama modu, TemplatedParent bir denetim şablonunun içinden şablonun uygulandığı çalışma zamanı nesne örneğine bağlamak için kullanılır. öğesinin Expanderkök öğesi olan öğesininControlTemplateBindingContext, şablonun uygulandığı çalışma zamanı nesne örneğine ayarlanmıştır. Bu nedenle, Expander ve alt öğeleri bağlama ifadelerini ve Binding nesnelerini nesnenin CardViewExpander özelliklerine karşı çözümler. , MultiBinding iki Binding nesnenin Expander.IsVisible AllTrueMultiConverter değerlendirmesinin truesağlanması koşuluyla özelliğini ayarlamak için true örneğini kullanır. Aksi takdirde özelliği Expander.IsVisible olarak falseayarlanır.

Göreli bağlamalar hakkında daha fazla bilgi için bkz . Xamarin.Forms Göreli Bağlamaları. Denetim şablonları hakkında daha fazla bilgi için bkz . Xamarin.Forms Denetim Şablonları.