Aracılığıyla paylaş


Değer dönüştürücüleri bağlama

Browse sample. Örneğe göz atın

.NET Çok Platformlu Uygulama Kullanıcı Arabirimi (.NET MAUI) veri bağlamaları genellikle bir kaynak özellikten hedef özelliğe ve bazı durumlarda hedef özellikten kaynak özelliğe veri aktarır. Bu aktarım, kaynak ve hedef özellikler aynı türde olduğunda veya bir türün örtük dönüştürme yoluyla diğer türe dönüştürülebildiği durumlarda basittir. Böyle bir durum söz konusu olmadığında, bir tür dönüştürme gerçekleştirilmelidir.

Dize biçimlendirme makalesinde, herhangi bir türü dizeye dönüştürmek için veri bağlama özelliğini nasıl kullanabileceğinizi StringFormat gördünüz. Diğer dönüştürme türleri için arabirimini uygulayan bir sınıfta bazı özel kodlar IValueConverter yazmanız gerekir. Uygulayan IValueConverter sınıflar değer dönüştürücüleri olarak adlandırılır, ancak bunlar genellikle bağlama dönüştürücüleri veya bağlama değer dönüştürücüleri olarak da adlandırılır.

Değer dönüştürücüleri bağlama

Kaynak özelliğin türünde int olduğu ancak hedef özelliğin bir boololduğu bir veri bağlaması tanımlamak istediğinizi varsayalım. Bu veri bağlamasının, tamsayı kaynağı 0'a eşit olduğunda bir false değer üretmesini ve true aksi takdirde olmasını istiyorsunuz. Bu, arabirimini uygulayan IValueConverter bir sınıfla elde edilebilir:

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

Ardından bu sınıfın bir örneğini sınıfın Converter Binding özelliğine veya Converter işaretleme uzantısının özelliğine Binding ayarlarsınız. Bu sınıf, veri bağlamanın bir parçası olur.

veri Convert kaynağından veya bağlamalarındaki hedefe geçtiğinde OneWay TwoWay yöntemi çağrılır. value parametresi, veri bağlama kaynağındaki nesne veya değerdir. yöntemi, veri bağlama hedefinin türünde bir değer döndürmelidir. Burada gösterilen yöntem parametresini bir int değerine value dönüştürür ve ardından dönüş değeri için bool 0 ile karşılaştırır.

ConvertBack yöntemi, veriler hedeften veya OneWayToSource bağlamalarındaki kaynağa geçtiğinde TwoWay çağrılır. ConvertBack ters dönüştürme gerçekleştirir: Parametresinin value hedeften bir bool olduğunu varsayar ve bunu kaynak için bir int dönüş değerine dönüştürür.

Dekont

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

Aşağıdaki örnekte bu değer dönüştürücüsunun bir veri bağlamasında nasıl kullanılacağı gösterilmektedir:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:DataBindingDemos"
             x:Class="DataBindingDemos.EnableButtonsPage"
             Title="Enable Buttons">
    <ContentPage.Resources>
        <local:IntToBoolConverter x:Key="intToBool" />
    </ContentPage.Resources>

    <StackLayout Padding="10, 0">
        <Entry x:Name="entry1"
               Text=""
               Placeholder="enter search term"
               VerticalOptions="Center" />
        <Button x:DataType="Entry"
                Text="Search"
                HorizontalOptions="Center"
                VerticalOptions="Center"
                IsEnabled="{Binding Source={x:Reference entry1},
                                    Path=Text.Length,
                                    Converter={StaticResource intToBool}}" />
        <Entry x:Name="entry2"
               Text=""
               Placeholder="enter destination"
               VerticalOptions="Center" />
        <Button x:DataType="Entry"
                Text="Submit"
                HorizontalOptions="Center"
                VerticalOptions="Center"
                IsEnabled="{Binding Source={x:Reference entry2},
                                    Path=Text.Length,
                                    Converter={StaticResource intToBool}}" />
    </StackLayout>
</ContentPage>

Bu örnekte, IntToBoolConverter örneği sayfanın kaynak sözlüğünde oluşturulur. Ardından, özelliği iki veri bağlamasında ayarlamak Converter için bir StaticResource işaretleme uzantısıyla başvurulur. Veri dönüştürücülerini sayfadaki birden çok veri bağlaması arasında paylaşmak çok yaygındır. Uygulamanızın birden çok sayfasında bir değer dönüştürücüsü kullanılıyorsa, bunu uygulama düzeyi kaynak sözlüğünde başlatabilirsiniz.

Bu örnek, kullanıcının bir görünüme girdiği metne göre bir işlem gerçekleştirdiğinde Button yaygın bir Entry gereksinimi gösterir. Text Özelliği varsayılan olarak olduğundan ve bu durumda veri bağlama çalışmayacağından her Entry birinin özelliği null boş bir dizeye Text başlatılır. içine hiçbir şey yazılmadıysa Entry, Button devre dışı bırakılmalıdır. Her Button birinin özelliğinde bir veri bağlaması IsEnabled vardır. Veri bağlama kaynağı, ilgili Entryözelliğinin özelliğidir.Text Length Bu Length özellik 0 değilse, değer dönüştürücüsü döndürülüyor true ve Button etkin:

Enable buttons.

Dekont

Değer dönüştürücüsünü yalnızca bağlamalarda OneWay kullanılabileceğini biliyorsanız yöntemi ConvertBack yalnızca döndürebilir null.

Yukarıda Convert gösterilen yöntem, bağımsız değişkenin value türünde int olduğunu ve dönüş değerinin türünde boololması gerektiğini varsayar. Benzer şekilde, ConvertBack yöntemi bağımsız değişkenin value türünde bool ve dönüş değerinin olduğunu intvarsayar. Böyle bir durum söz konusu değilse, bir çalışma zamanı özel durumu oluşur.

Daha genelleştirilecek ve birkaç farklı veri türünü kabul etmek için değer dönüştürücüleri yazabilirsiniz. Convert ve ConvertBack yöntemleri parametresiyle value veya is işleçlerini kullanabilir as veya türünü belirlemek için bu parametreyi çağırabilir GetType ve ardından uygun bir şey yapabilir. Her yöntemin dönüş değerinin beklenen türü parametresi tarafından targetType verilir. Bazen değer dönüştürücüleri farklı hedef türlerdeki veri bağlamalarıyla birlikte kullanılır. Bu durumda değer dönüştürücüsü, doğru tür için dönüştürme gerçekleştirmek üzere bağımsız değişkenini kullanabilir targetType .

Gerçekleştirilen dönüştürme farklı kültürler için farklıysa, bu amaç için parametresini culture kullanın.

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

Değer dönüştürücü sınıflarının özellikleri ve genel parametreleri olabilir. Aşağıdaki değer dönüştürücüsü, kaynaktan hedef için türünde T bir nesneye dönüştürürbool:

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

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

Aşağıdaki örnekte, bu dönüştürücü bir görünümün değerini görüntülemek için nasıl kullanılabilir gösterilmektedir Switch . Değer dönüştürücülerinin kaynak sözlüğünde kaynak olarak örnek olarak gösterilmesi yaygın olsa da, bu örnekte bir alternatif gösterilmektedir. Burada her değer dönüştürücüsü, özellik öğesi etiketleri arasında Binding.Converter örnek oluşturulur. x:TypeArguments, genel bağımsız değişkeni gösterir ve TrueObject FalseObject her ikisi de bu tür nesnelere ayarlanır:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:DataBindingDemos"
             x:Class="DataBindingDemos.SwitchIndicatorsPage"
             Title="Switch Indicators">
    <ContentPage.Resources>
        <Style TargetType="Label">
            <Setter Property="FontSize" Value="18" />
            <Setter Property="VerticalOptions" Value="Center" />
        </Style>

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

    <StackLayout Padding="10, 0">
        <StackLayout Orientation="Horizontal"
                     VerticalOptions="Center">
            <Label Text="Subscribe?" />
            <Switch x:Name="switch1" />
            <Label>
                <Label.Text>
                    <Binding x:DataType="Switch"
                             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="Center">
            <Label Text="Allow popups?" />
            <Switch x:Name="switch2" />
            <Label>
                <Label.Text>
                    <Binding x:DataType="Switch"
                             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 x:DataType="Switch"
                             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="Center">
            <Label Text="Learn more?" />
            <Switch x:Name="switch3" />
            <Label FontSize="18"
                   VerticalOptions="Center">
                <Label.Style>
                    <Binding x:DataType="Switch"
                             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>

Bu örnekte, üç Switch ve Label çiftinin son kısmında genel bağımsız değişken olarak Styleayarlanır ve ve FalseObjectdeğerleri TrueObject için nesnelerin tamamı Style sağlanır. Bunlar, kaynak sözlüğünde ayarlanan örtük stili Label geçersiz kılar, böylece bu stildeki özellikler açıkça öğesine Labelatanır. geçişini yapmak Switch , karşılık gelenin Label değişikliği yansıtmasına neden olur:

Switch indicators.

Dekont

Diğer görünümlere göre kullanıcı arabiriminde değişiklik uygulamak için tetikleyicileri kullanmak da mümkündür. Daha fazla bilgi için bkz. Tetikleyiciler.

Bağlayıcı dönüştürücü parametreleri

Binding sınıfı bir ConverterParameter özelliği Binding ve işaretleme uzantısı da bir ConverterParameter özelliği tanımlar. Bu özellik ayarlanırsa, değer bağımsız değişken olarak ve ConvertBack yöntemlerine parameter geçirilirConvert. Değer dönüştürücüsünün örneği birkaç veri bağlaması arasında paylaşılsa bile, ConverterParameter farklı dönüştürmeler gerçekleştirmek için farklı olabilir.

özelliğinin ConverterParameter kullanımı bir renk seçimi programıyla gösterilebilir. Aşağıdaki örnekte , adlı RedGreenüç tür özelliğine float sahip olan ve Blue bir Color değer oluşturmak için kullandığı öğesi gösterilmektedirRgbColorViewModel:

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

    public event PropertyChangedEventHandler PropertyChanged;

    public float Red
    {
        get { return color.Red; }
        set
        {
            if (color.Red != value)
            {
                Color = new Color(value, color.Green, color.Blue);
            }
        }
    }

    public float Green
    {
        get { return color.Green; }
        set
        {
            if (color.Green != value)
            {
                Color = new Color(color.Red, value, color.Blue);
            }
        }
    }

    public float Blue
    {
        get { return color.Blue; }
        set
        {
            if (color.Blue != value)
            {
                Color = new Color(color.Red, color.Green, value);
            }
        }
    }

    public Color Color
    {
        get { return 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);
            }
        }
    }

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

Red, Greenve Blue özellik değerleri 0 ile 1 arasında olabilir. 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örüntülemek için, bunların 255 ile çarpılması, tamsayıya dönüştürülmesi ve ardından özelliğinde StringFormat "X2" belirtimi ile biçimlendirilmesi gerekir. 255 ile çarpma ve tamsayıya dönüştürme, değer dönüştürücüsü tarafından gerçekleştirilebilir. Değer dönüştürücüsünün mümkün olduğunca genelleştirilmesi için çarpma faktörü özelliğiyle ConverterParameter belirtilebilir; başka bir deyişle bağımsız değişken olarak parameter ve ConvertBack yöntemlerini girerConvert:

public class FloatToIntConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (int)Math.Round((float)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 float)
            return (float)parameter;
        else if (parameter is int)
            return (int)parameter;
        else if (parameter is string)
            return float.Parse((string)parameter);

        return 1;
    }
}

Bu örnekte yöntemi, Convert değeriyle çarparken bir'den'e float int parameter dönüştürür. yöntemi, ConvertBack tamsayı value bağımsız değişkenini ölçütüne parameter böler ve bir float sonuç döndürür.

Bağımsız değişkenin türü, veri bağlamanın parameter XAML'de mi yoksa kodda mı tanımlandığına bağlı olarak farklı olabilir. ConverterParameter özelliği Binding kodda ayarlandıysa, büyük olasılıkla sayısal bir değere ayarlanmıştır:

binding.ConverterParameter = 255;

ConverterParameter özelliği türünde Objectolduğundan, C# derleyicisi değişmez değeri 255'i tamsayı olarak yorumlar ve özelliği bu değere ayarlar.

Ancak, XAML'de ConverterParameter şu şekilde ayarlanmış olabilir:

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

255, türünden Objectdolayı ConverterParameter bir sayı gibi görünse de, XAML ayrıştırıcısı 255'i dize olarak ele alır. Bu nedenle, değer dönüştürücüsü , intveya stringtüründe floatolma durumlarını parameter işleyen ayrı GetParameter bir yöntem içerir.

Aşağıdaki XAML örneği, kaynak sözlüğünde örneği FloatToIntConverter gösterir:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:DataBindingDemos"
             x:Class="DataBindingDemos.RgbColorSelectorPage"
             Title="RGB Color Selector"
             x:DataType="local:RgbColorViewModel">
    <ContentPage.BindingContext>
        <local:RgbColorViewModel Color="Gray" />
    </ContentPage.BindingContext>
    <ContentPage.Resources>
        <Style TargetType="Slider">
            <Setter Property="VerticalOptions" Value="Center" />
        </Style>

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

        <local:FloatToIntConverter x:Key="floatToInt" />
    </ContentPage.Resources>

    <StackLayout Margin="20">
        <BoxView Color="{Binding Color}"
                 HeightRequest="100"
                 WidthRequest="100"
                 HorizontalOptions="Center" />
        <StackLayout Margin="10, 0">
            <Label Text="{Binding Name}" />
            <Slider Value="{Binding Red}" />
            <Label Text="{Binding Red,
                                  Converter={StaticResource floatToInt},
                                  ConverterParameter=255,
                                  StringFormat='Red = {0:X2}'}" />
            <Slider Value="{Binding Green}" />
            <Label Text="{Binding Green,
                                  Converter={StaticResource floatToInt},
                                  ConverterParameter=255,
                                  StringFormat='Green = {0:X2}'}" />
            <Slider Value="{Binding Blue}" />
            <Label>
                <Label.Text>
                    <Binding Path="Blue"
                             StringFormat="Blue = {0:X2}"
                             Converter="{StaticResource floatToInt}">
                        <Binding.ConverterParameter>
                            <x:Single>255</x:Single>
                        </Binding.ConverterParameter>
                    </Binding>
                </Label.Text>
            </Label>
        </StackLayout>
    </StackLayout>
</ContentPage>

ve Green özelliklerinin değerleri Red bir Binding işaretleme uzantısıyla görüntülenir. Blue Ancak özelliği, açık float bir değerin özelliğine nasıl ayarlanabileceğini göstermek için ConverterParameter sınıfını Binding başlatır:

RGB color selector.