Xamarin.FormsBağlama değeri dönüştürücüleri

Örnek indirin örnek indirin

Veri bağlamaları genellikle verileri bir kaynak özelliğinden Target özelliğine aktarır ve bazı durumlarda Target özelliğinden Source özelliğine. Bu aktarım, kaynak ve hedef özellikler aynı türde olduğunda veya bir tür örtük bir dönüştürme yoluyla diğer türe dönüştürülebileceği zaman basittir. Böyle bir durum değilse, bir tür dönüştürme gerçekleşmelidir.

Dize biçimlendirme makalesinde, StringFormat bir tür dizeyi bir dizeye dönüştürmek için bir veri bağlamanın özelliğini nasıl kullanabileceğinizi gördünüz. Diğer dönüştürme türleri için, arabirimi uygulayan bir sınıfa bazı özel kod yazmanız gerekir IValueConverter . (Evrensel Windows Platformu ad alanında adlı benzer bir sınıfı içerir IValueConverter Windows.UI.Xaml.Data , ancak bu IValueConverter Xamarin.Forms ad alanıdır.) Uygulayan sınıflara IValueConverter değer dönüştürücülerdenir, ancak genellikle bağlama dönüştürücüleri veya bağlama değeri dönüştürücüleriolarak da anılır.

IValueConverter arabirimi

Kaynak özelliğin türü olan int ancak Target özelliği bir olan veri bağlamayı tanımlamak istediğinizi varsayalım bool . Bu veri bağlamasının, false tamsayı kaynağı 0 ' a eşit olduğunda bir değer oluşturmasını ve true Aksi takdirde.

Bunu, arabirimini uygulayan bir sınıf ile yapabilirsiniz IValueConverter :

public class IntToBoolConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (int)value != 0;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (bool)value ? 1 : 0;
    }
}

Bu sınıfın bir örneğini Converter Binding sınıfının özelliğine veya Converter Binding biçimlendirme uzantısının özelliğine ayarlarsınız. Bu sınıf veri bağlamasının bir parçası haline gelir.

Bu Convert Yöntem, veriler kaynaktan hedefe OneWay veya bağlamalara geçdiğinde çağrılır TwoWay . valueParametresi, veri bağlama kaynağından alınan nesne veya değerdir. Yöntem, veri bağlama hedefinin türünün bir değerini döndürmelidir. Burada gösterilen yöntemi value parametresini öğesine yayınlar int ve sonra dönüş değeri için 0 ile karşılaştırır bool .

ConvertBackVeriler hedeften kaynağına TwoWay veya OneWayToSource bağlamalara geldiğinde çağrılır. ConvertBackters dönüştürmeyi gerçekleştirir: value parametrenin hedeften bir olduğunu varsayar bool ve int kaynak için bir dönüş değerine dönüştürür.

Veri bağlama de bir StringFormat ayar içeriyorsa, sonuç bir dize olarak biçimlendirilmeden önce değer Dönüştürücüsü çağrılır.

Veri bağlama gösterileri örneğinde düğmeleri etkinleştir sayfası, bu değer dönüştürücünün bir veri bağlamasında nasıl kullanılacağını gösterir. , IntToBoolConverter Sayfanın kaynak sözlüğünde oluşturulur. Daha sonra, StaticResource Converter iki veri bağlamalarında özelliği ayarlamak için bir biçimlendirme uzantısıyla başvurulur. Veri dönüştürücülerinin sayfada birden çok veri bağlaması arasında paylaşılması çok yaygındı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.EnableButtonsPage"
             Title="Enable Buttons">
    <ContentPage.Resources>
        <ResourceDictionary>
            <local:IntToBoolConverter x:Key="intToBool" />
        </ResourceDictionary>
    </ContentPage.Resources>

    <StackLayout Padding="10, 0">
        <Entry x:Name="entry1"
               Text=""
               Placeholder="enter search term"
               VerticalOptions="CenterAndExpand" />

        <Button Text="Search"
                HorizontalOptions="Center"
                VerticalOptions="CenterAndExpand"
                IsEnabled="{Binding Source={x:Reference entry1},
                                    Path=Text.Length,
                                    Converter={StaticResource intToBool}}" />

        <Entry x:Name="entry2"
               Text=""
               Placeholder="enter destination"
               VerticalOptions="CenterAndExpand" />

        <Button Text="Submit"
                HorizontalOptions="Center"
                VerticalOptions="CenterAndExpand"
                IsEnabled="{Binding Source={x:Reference entry2},
                                    Path=Text.Length,
                                    Converter={StaticResource intToBool}}" />
    </StackLayout>
</ContentPage>

Uygulamanızın birden çok sayfasında bir değer dönüştürücüsü kullanılıyorsa, app. xaml dosyasındaki kaynak sözlüğünde örneğini oluşturabilirsiniz.

Düğmeleri etkinleştir sayfası, Button kullanıcının bir görünüme sahip olduğu metne göre bir işlem gerçekleştirdiğinde bir genel gereksinimi gösterir Entry . Öğesine hiçbir şey yazılmışsa, Entry Button devre dışı bırakılmalıdır. Her biri Button , özelliği üzerinde bir veri bağlama içerir IsEnabled . Veri bağlama kaynağı, Length Text karşılık gelen özelliğin özelliğidir Entry . Bu Length özellik 0 değilse, değer Dönüştürücüsü döndürülür true ve Button etkinleştirilir:

Düğmeleri etkinleştir

TextHer birinin içindeki özelliğinin Entry boş bir dizeye başlatıldığını unutmayın. TextÖzelliği varsayılan olarak olur null ve veri bağlama bu durumda çalışmayacaktır.

Bazı değer dönüştürücüler özellikle belirli uygulamalar için yazılmıştır, diğerleri genelleştirilir. Bir değer dönüştürücünün yalnızca OneWay bağlamalarda kullanılacağını biliyorsanız, ConvertBack yöntemi yalnızca döndürebilir null .

ConvertYukarıda gösterilen yöntem value bağımsız değişkenin tür olduğunu int ve dönüş değerinin türünden olması gerektiğini varsayar bool . Benzer şekilde, ConvertBack yöntemi value bağımsız değişkenin tür olduğunu bool ve dönüş değerinin olduğunu varsayar int . Durum bu değilse, bir çalışma zamanı özel durumu oluşur.

Daha genelleştirilebilmeniz ve birçok farklı veri türünü kabul etmek için değer dönüştürücülerini yazabilirsiniz. ConvertVe ConvertBack yöntemleri as is parametresiyle veya işleçlerini kullanabilir ya da value GetType Bu parametreyi kullanarak türünü belirleyebilir ve uygun bir şeyi gerçekleştirebilir. Her yöntemin dönüş değerinin beklenen türü parametre tarafından verilir targetType . Bazen, değer dönüştürücüler farklı hedef türlerin veri bağlamaları ile kullanılır; değer Dönüştürücüsü, targetType doğru tür için bir dönüştürme gerçekleştirmek için bağımsız değişkenini kullanabilir.

Gerçekleştirilen dönüştürme farklı kültürler için farklıysa, culture Bu amaçla parametresini kullanın. parameterVe için bağımsız Convert değişkeni ConvertBack Bu makalenin ilerleyen kısımlarında ele alınmıştır.

Bağlama dönüştürücü özellikleri

Değer dönüştürücü sınıflarında Özellikler ve genel parametreler bulunabilir. Bu belirli değer Dönüştürücüsü, bool kaynağı kaynağından hedef için türünden bir nesneye dönüştürür T :

public class BoolToObjectConverter<T> : IValueConverter
{
    public T TrueObject { set; get; }

    public T FalseObject { set; get; }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (bool)value ? TrueObject : FalseObject;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return ((T)value).Equals(TrueObject);
    }
}

Anahtar göstergeleri sayfası, bir görünümün değerini görüntülemek için nasıl kullanılabileceğini gösterir Switch . Değer dönüştürücülerinin kaynak sözlüğünde kaynak olarak örneğinin oluşturulması yaygın olsa da bu sayfada bir alternatif gösterilir: her bir değer Dönüştürücüsü, Binding.Converter özellik öğesi etiketleri arasında oluşturulur. , x:TypeArguments Genel bağımsız değişkenini gösterir ve TrueObject FalseObject her ikisi de bu türdeki nesneler olarak ayarlanı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.SwitchIndicatorsPage"
             Title="Switch Indicators">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style TargetType="Label">
                <Setter Property="FontSize" Value="18" />
                <Setter Property="VerticalOptions" Value="Center" />
            </Style>

            <Style TargetType="Switch">
                <Setter Property="VerticalOptions" Value="Center" />
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>

    <StackLayout Padding="10, 0">
        <StackLayout Orientation="Horizontal"
                     VerticalOptions="CenterAndExpand">
            <Label Text="Subscribe?" />
            <Switch x:Name="switch1" />
            <Label>
                <Label.Text>
                    <Binding Source="{x:Reference switch1}"
                             Path="IsToggled">
                        <Binding.Converter>
                            <local:BoolToObjectConverter x:TypeArguments="x:String"
                                                         TrueObject="Of course!"
                                                         FalseObject="No way!" />
                        </Binding.Converter>
                    </Binding>
                </Label.Text>
            </Label>
        </StackLayout>

        <StackLayout Orientation="Horizontal"
                     VerticalOptions="CenterAndExpand">
            <Label Text="Allow popups?" />
            <Switch x:Name="switch2" />
            <Label>
                <Label.Text>
                    <Binding Source="{x:Reference switch2}"
                             Path="IsToggled">
                        <Binding.Converter>
                            <local:BoolToObjectConverter x:TypeArguments="x:String"
                                                         TrueObject="Yes"
                                                         FalseObject="No" />
                        </Binding.Converter>
                    </Binding>
                </Label.Text>
                <Label.TextColor>
                    <Binding Source="{x:Reference switch2}"
                             Path="IsToggled">
                        <Binding.Converter>
                            <local:BoolToObjectConverter x:TypeArguments="Color"
                                                         TrueObject="Green"
                                                         FalseObject="Red" />
                        </Binding.Converter>
                    </Binding>
                </Label.TextColor>
            </Label>
        </StackLayout>

        <StackLayout Orientation="Horizontal"
                     VerticalOptions="CenterAndExpand">
            <Label Text="Learn more?" />
            <Switch x:Name="switch3" />
            <Label FontSize="18"
                   VerticalOptions="Center">
                <Label.Style>
                    <Binding Source="{x:Reference switch3}"
                             Path="IsToggled">
                        <Binding.Converter>
                            <local:BoolToObjectConverter x:TypeArguments="Style">
                                <local:BoolToObjectConverter.TrueObject>
                                    <Style TargetType="Label">
                                        <Setter Property="Text" Value="Indubitably!" />
                                        <Setter Property="FontAttributes" Value="Italic, Bold" />
                                        <Setter Property="TextColor" Value="Green" />
                                    </Style>                                    
                                </local:BoolToObjectConverter.TrueObject>

                                <local:BoolToObjectConverter.FalseObject>
                                    <Style TargetType="Label">
                                        <Setter Property="Text" Value="Maybe later" />
                                        <Setter Property="FontAttributes" Value="None" />
                                        <Setter Property="TextColor" Value="Red" />
                                    </Style>
                                </local:BoolToObjectConverter.FalseObject>
                            </local:BoolToObjectConverter>
                        </Binding.Converter>
                    </Binding>
                </Label.Style>
            </Label>
        </StackLayout>
    </StackLayout>
</ContentPage>

Üç Switch ve çiftinin en sonunda Label , genel bağımsız değişken olarak ayarlanır Style ve tüm Style nesneleri ve değerleri için sağlanır TrueObject FalseObject . Bunlar, kaynak sözlüğünde ayarlanan örtülü stilini geçersiz kılar Label , bu nedenle söz konusu stildeki Özellikler açıkça öğesine atanır Label . SwitchBunu değiştirmek, karşılık gelen Label değişikliği yansıtmasına neden olur:

Anahtar göstergeleri

TriggersDiğer görünümlere göre Kullanıcı arabirimindeki benzer değişiklikleri uygulamak için de kullanabilirsiniz.

Bağlama dönüştürücü parametreleri

BindingSınıfı bir özelliği tanımlar ConverterParameter ve Binding biçimlendirme uzantısı da bir ConverterParameter özelliği tanımlar. Bu özellik ayarlandıysa, değeri Convert ConvertBack bağımsız değişkeni olarak ve yöntemlerine geçirilir parameter . Değer dönüştürücünün örneği çeşitli veri bağlamaları arasında paylaşılsa bile, ConverterParameter farklı dönüştürmeler gerçekleştirmek için farklı olabilir.

Kullanımı, ConverterParameter renk seçim programı ile gösterilmiştir. Bu durumda, RgbColorViewModel öğesinin double adlı, Red Green ve Blue bir değer oluşturmak için kullandığı Color türünde üç özelliği vardır:

public class RgbColorViewModel : INotifyPropertyChanged
{
    Color color;
    string name;

    public event PropertyChangedEventHandler PropertyChanged;

    public double Red
    {
        set
        {
            if (color.R != value)
            {
                Color = new Color(value, color.G, color.B);
            }
        }
        get
        {
            return color.R;
        }
    }

    public double Green
    {
        set
        {
            if (color.G != value)
            {
                Color = new Color(color.R, value, color.B);
            }
        }
        get
        {
            return color.G;
        }
    }

    public double Blue
    {
        set
        {
            if (color.B != value)
            {
                Color = new Color(color.R, color.G, value);
            }
        }
        get
        {
            return color.B;
        }
    }

    public Color Color
    {
        set
        {
            if (color != value)
            {
                color = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Red"));
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Green"));
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Blue"));
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Color"));

                Name = NamedColor.GetNearestColorName(color);
            }
        }
        get
        {
            return color;
        }
    }

    public string Name
    {
        private set
        {
            if (name != value)
            {
                name = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Name"));
            }
        }
        get
        {
            return name;
        }
    }
}

Red, Green Ve Blue Özellikleri 0 ile 1 arasında değişir. Ancak, bileşenlerin iki basamaklı onaltılık değerler olarak görüntülenmesini tercih edebilirsiniz.

Bunları XAML 'de onaltılık değerler olarak göstermek için, 255 ile çarpılmaları, bir tamsayıya dönüştürülmesi ve sonra özelliğindeki "X2" belirtimine göre biçimlendirilmesi gerekir StringFormat . İlk iki görev (255 ile çarpma ve bir tamsayıya dönüştürme), değer Dönüştürücüsü tarafından işlenebilir. Değer dönüştürücüsünü mümkün olduğunca genelleştirilemez hale getirmek için çarpma faktörü özelliği ile belirtilebilir ConverterParameter , yani Convert ConvertBack bağımsız değişken olarak ve yöntemlerini girer parameter .

public class DoubleToIntConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (int)Math.Round((double)value * GetParameter(parameter));
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (int)value / GetParameter(parameter);
    }

    double GetParameter(object parameter)
    {
        if (parameter is double)
            return (double)parameter;

        else if (parameter is int)
            return (int)parameter;

        else if (parameter is string)
            return double.Parse((string)parameter);

        return 1;
    }
}

, Convert double int Değerine göre çarpırken öğesine dönüştürür parameter ; ConvertBack tamsayı value bağımsız değişkenini ile böler parameter ve bir double sonuç döndürür. (Aşağıda gösterilen programda, değer dönüştürücüsü yalnızca dize biçimlendirmesi ile bağlantılı olarak kullanılır, bu nedenle ConvertBack kullanılmaz.)

Bağımsız değişkenin türü, parameter veri bağlamasının kodda veya xaml 'de tanımlanıp tanımlanmayacağı konusunda farklılık açmış olabilir. ConverterParameterÖzelliği Binding kodda ayarlandıysa, büyük olasılıkla sayısal bir değere ayarlanabilir:

binding.ConverterParameter = 255;

ConverterParameterÖzelliği türündedir Object , bu nedenle C# derleyicisi 255 sabit değerini bir tamsayı olarak yorumlar ve özelliği bu değere ayarlar.

Ancak XAML 'de, ConverterParameter bunun gibi büyük olasılıkla şöyle ayarlanabilir:

<Label Text="{Binding Red,
                      Converter={StaticResource doubleToInt},
                      ConverterParameter=255,
                      StringFormat='Red = {0:X2}'}" />

255 bir sayı gibi görünür, ancak ConverterParameter türünde olduğu IÇIN Object XAML ayrıştırıcısı, 255 öğesini bir dize olarak değerlendirir.

Bu nedenle, yukarıda gösterilen değer dönüştürücüsü GetParameter parameter ,, veya türünde olma durumlarını işleyen ayrı bir yöntem içerir double int string .

RGB Renk Seçicisi sayfası, DoubleToIntConverter kaynak sözlüğünde iki örtük stilin tanımını izleyen bir örneği oluşturur:

<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.RgbColorSelectorPage"
             Title="RGB Color Selector">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style TargetType="Slider">
                <Setter Property="VerticalOptions" Value="CenterAndExpand" />
            </Style>

            <Style TargetType="Label">
                <Setter Property="HorizontalTextAlignment" Value="Center" />
            </Style>

            <local:DoubleToIntConverter x:Key="doubleToInt" />
        </ResourceDictionary>
    </ContentPage.Resources>

    <StackLayout>
        <StackLayout.BindingContext>
            <local:RgbColorViewModel Color="Gray" />
        </StackLayout.BindingContext>

        <BoxView Color="{Binding Color}"
                 VerticalOptions="FillAndExpand" />

        <StackLayout Margin="10, 0">
            <Label Text="{Binding Name}" />

            <Slider Value="{Binding Red}" />
            <Label Text="{Binding Red,
                                  Converter={StaticResource doubleToInt},
                                  ConverterParameter=255,
                                  StringFormat='Red = {0:X2}'}" />

            <Slider Value="{Binding Green}" />
            <Label Text="{Binding Green,
                                  Converter={StaticResource doubleToInt},
                                  ConverterParameter=255,
                                  StringFormat='Green = {0:X2}'}" />

            <Slider Value="{Binding Blue}" />
            <Label>
                <Label.Text>
                    <Binding Path="Blue"
                             StringFormat="Blue = {0:X2}"
                             Converter="{StaticResource doubleToInt}">
                        <Binding.ConverterParameter>
                            <x:Double>255</x:Double>
                        </Binding.ConverterParameter>
                    </Binding>
                </Label.Text>
            </Label>
        </StackLayout>
    </StackLayout>
</ContentPage>    

Ve özelliklerinin değerleri, Red Green Binding biçimlendirme uzantısıyla birlikte görüntülenir. BlueAncak özelliği, Binding bir açık double değerin özelliği olarak nasıl ayarlanbildiğini göstermek için sınıfını başlatır ConverterParameter .

Sonuç şu şekildedir:

RGB Renk Seçicisi