Sdílet prostřednictvím


Převaděče hodnot vazeb

Browse sample. Procházení ukázky

Datové vazby .NET Multi-Platform App UI (.NET MAUI) obvykle přenášejí data ze zdrojové vlastnosti do cílové vlastnosti a v některých případech z cílové vlastnosti do zdrojové vlastnosti. Tento přenos je jednoduchý, pokud jsou vlastnosti zdroje a cíle stejného typu nebo pokud lze jeden typ převést na druhý typ prostřednictvím implicitního převodu. Pokud tomu tak není, musí proběhnout převod typu.

V článku Formátování řetězce jste viděli, jak můžete použít StringFormat vlastnost datové vazby k převodu libovolného typu na řetězec. Pro jiné typy převodů je nutné napsat nějaký specializovaný kód ve třídě, která implementuje IValueConverter rozhraní. Třídy, které implementují IValueConverter , se nazývají převaděče hodnot, ale také se často označují jako převaděče vazeb nebo převaděče hodnot vazby.

Převaděče hodnot vazeb

Předpokládejme, že chcete definovat datovou vazbu, kde je zdrojová vlastnost typuint, ale cílová vlastnost je .bool Chcete, aby tato datová vazba generuje false hodnotu, pokud je celočíselná zdroj rovna 0, a true jinak. Toho lze dosáhnout pomocí třídy, která implementuje IValueConverter rozhraní:

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

Potom nastavíte instanci této třídy na Converter vlastnost Binding třídy nebo na Converter vlastnost Binding rozšíření značek. Tato třída se stane součástí datové vazby.

Metoda Convert se volá při přesunu dat ze zdroje do cíle v OneWay vazbách nebo TwoWay vazbách. Parametr value je objekt nebo hodnota ze zdroje datové vazby. Metoda musí vrátit hodnotu typu cíle datové vazby. Zde zobrazená metoda přetypuje value parametr na hodnotu int a pak ji porovná s hodnotou 0 pro návratovou bool hodnotu.

Metoda ConvertBack se volá, když se data přesunou z cíle do zdroje nebo TwoWayOneWayToSource vazby. ConvertBack provádí opačný převod: Předpokládá, že value parametr je bool z cíle, a převede ho na návratovou int hodnotu pro zdroj.

Poznámka:

Pokud datová vazba obsahuje StringFormat také nastavení, převaděč hodnot se vyvolá před formátováním výsledku jako řetězec.

Následující příklad ukazuje použití tohoto převaděče hodnot v datové vazbě:

<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 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 Text="Submit"
                HorizontalOptions="Center"
                VerticalOptions="Center"
                IsEnabled="{Binding Source={x:Reference entry2},
                                    Path=Text.Length,
                                    Converter={StaticResource intToBool}}" />
    </StackLayout>
</ContentPage>

V tomto příkladu se IntToBoolConverter vytvoří instance ve slovníku prostředků stránky. Pak se odkazuje s rozšířením StaticResource značek, které Converter nastaví vlastnost ve dvou datových vazbách. Sdílení převaděčů dat mezi několika datovými vazbami na stránce je velmi běžné. Pokud se převaděč hodnot používá na více stránkách vaší aplikace, můžete ho vytvořit instanci ve slovníku prostředků na úrovni aplikace.

Tento příklad ukazuje běžnou potřebu, když Button provede operaci na základě textu, který uživatel zadá do Entry zobrazení. Text Vlastnost každého z nich Entry se inicializuje na prázdný řetězec, protože Text vlastnost je null ve výchozím nastavení a v takovém případě datová vazba nebude fungovat. Pokud do souboru Entrynení zadáno nic, Button mělo by být zakázáno. Každá Button obsahuje datovou vazbu pro svou IsEnabled vlastnost. Zdroj vazby dat je Length vlastnost Text vlastnosti odpovídající Entry. Pokud tato Length vlastnost není 0, vrátí true převaděč hodnot a Button je povolen:

Enable buttons.

Poznámka:

Pokud víte, že převaděč hodnot bude použit pouze ve OneWay vazbách, pak ConvertBack metoda může jednoduše vrátit null.

Výše Convert uvedená metoda předpokládá, že value argument je typu int a návratová hodnota musí být typu bool. Podobně metoda předpokládá, ConvertBack že value argument je typu bool a návratová hodnota je int. Pokud tomu tak není, dojde k výjimce za běhu.

Převaděče hodnot můžete napsat tak, aby byly obecnější a přijímaly několik různých typů dat. Tyto Convert metody ConvertBack mohou použít as nebo is operátory s parametrem value , nebo můžou tento parametr volat GetType , aby určil jeho typ, a pak provést něco vhodného. Očekávaný typ návratové hodnoty každé metody je dán parametrem targetType . Někdy se převaděče hodnot používají s datovými vazbami různých cílových typů. V tomto případě může převaděč hodnot použít targetType argument k provedení převodu pro správný typ.

Pokud se převod provedený pro různé jazykové verze liší, použijte culture pro tento účel parametr.

Vlastnosti převaděče vazeb

Třídy převaděče hodnot mohou mít vlastnosti a obecné parametry. Následující převaděč hodnot převede bool zdroj na objekt typu T cíle:

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

Následující příklad ukazuje, jak lze tento převaděč použít k zobrazení hodnoty Switch zobrazení. I když je běžné vytvořit instanci převaděčů hodnot jako prostředky ve slovníku prostředků, tento příklad ukazuje alternativu. V této chvíli se vytvoří instance každého převaděče hodnot mezi Binding.Converter značkami property-element. Označuje x:TypeArguments obecný argument a TrueObjectFalseObject oba jsou nastaveny na objekty tohoto typu:

<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 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 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="Center">
            <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>

V tomto příkladu je v poslední ze tří Switch a Label párů obecný argument nastaven na Stylehodnotu a pro Style hodnoty TrueObjectFalseObjecta . Tyto přepisují implicitní styl pro Label sadu ve slovníku prostředků, takže vlastnosti v daném stylu jsou explicitně přiřazeny Label. Přepnutí Switch příčin odpovídajících Label změnám:

Switch indicators.

Poznámka:

Triggery je také možné použít k implementaci změn v uživatelském rozhraní na základě jiných zobrazení. Další informace najdete v tématu Aktivační události.

Parametry převaděče vazeb

Třída Binding definuje ConverterParameter vlastnost a Binding rozšíření značek také definuje ConverterParameter vlastnost. Pokud je tato vlastnost nastavena, je hodnota předána Convert do a ConvertBack metody jako parameter argument. I když je instance převaděče hodnot sdílena mezi několika datovými vazbami, ConverterParameter může se lišit při provádění různých převodů.

Použití ConverterParameter vlastnosti lze demonstrovat pomocí programu pro výběr barev. Následující příklad ukazuje RgbColorViewModel, který má tři vlastnosti typu float s názvem Red, Greena Blue že používá k vytvoření Color hodnoty:

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

Hodnoty Red, Greena Blue vlastností mohou být v rozsahu od 0 do 1. Můžete ale chtít, aby se komponenty zobrazovaly jako dvouciferné šestnáctkové hodnoty. Chcete-li tyto hodnoty zobrazit jako šestnáctkové hodnoty v jazyce XAML, musí být vynásobeny hodnotou 255, převedeny na celé číslo a poté formátovány se specifikací "X2" ve StringFormat vlastnosti. Násobení hodnotou 255 a převod na celé číslo lze provést převaděčem hodnot. Aby byl převaděč hodnot co nejobecně zobecněn, lze faktor násobení zadat pomocí ConverterParameter vlastnosti, což znamená, že jako argument zadává Convert a ConvertBack metody parameter :

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

V tomto příkladu Convert se metoda převede z hodnoty float na int a současně ji vynásobí parameter . Metoda ConvertBack vydělí celočíselné value argumenty parameter a vrátí float výsledek.

Typ argumentu parameter se pravděpodobně liší v závislosti na tom, jestli je datová vazba definovaná v jazyce XAML nebo kódu. ConverterParameter Pokud je vlastnost Binding nastavena v kódu, bude pravděpodobně nastavena na číselnou hodnotu:

binding.ConverterParameter = 255;

Vlastnost ConverterParameter je typu Object, takže kompilátor jazyka C# interpretuje literál 255 jako celé číslo a nastaví vlastnost na tuto hodnotu.

V XAML ConverterParameter se ale pravděpodobně nastaví takto:

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

I když 255 vypadá jako číslo, protože ConverterParameter je typu Object, analyzátor XAML považuje 255 za řetězec. Z tohoto důvodu převaděč hodnot obsahuje samostatnou GetParameter metodu, která zpracovává případy pro parameter typ float, intnebo string.

Následující příklad XAML vytvoří FloatToIntConverter instanci ve slovníku prostředků:

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

Hodnoty Red a Green vlastnosti jsou zobrazeny s rozšířením Binding značek. Vlastnost Blue však vytvoří instanci Binding třídy, aby ukázala, jak lze explicitní float hodnotu nastavit na ConverterParameter vlastnost:

RGB color selector.