Převaděče hodnot vazeb
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 TwoWay
OneWayToSource
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:
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 TrueObject
FalseObject
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 TrueObject
FalseObject
a . 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:
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
, Green
a 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
, Green
a 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
, int
nebo 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: