Xamarin.Forms Převaděče hodnot vazeb
Datové vazby 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ězců 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í. (Univerzální platforma Windows obsahuje podobnou třídu pojmenovanou IValueConverter
v Windows.UI.Xaml.Data
oboru názvů, ale to IValueConverter
je v Xamarin.Forms
oboru názvů.) 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.
IValueConverter – rozhraní
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.
Můžete to provést 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;
}
}
Instanci této třídy nastavíte 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.
Pokud datová vazba obsahuje StringFormat
také nastavení, převaděč hodnot se vyvolá před formátováním výsledku jako řetězec.
Stránka Povolit tlačítka v ukázce ukazuje, jak použít tento převaděč hodnot v datové vazbě. Vytvoří IntToBoolConverter
instanci ve slovníku prostředků stránky. Pak se odkazuje s rozšířením StaticResource
značek k nastavení Converter
vlastnosti ve dvou datových vazbách. Je velmi běžné sdílet převaděče dat mezi několika datovými vazbami na stránce:
<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>
Pokud se převaděč hodnot používá na více stránkách vaší aplikace, můžete ho vytvořit ve slovníku prostředků v souboru App.xaml .
Stránka Povolit tlačítka ukazuje běžnou potřebu při Button
provádění operace na základě textu, který uživatel zadá do Entry
zobrazení. Pokud do souboru Entry
není 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:
Všimněte si, že Text
vlastnost v každé Entry
z nich je inicializována na prázdný řetězec. Vlastnost Text
je null
ve výchozím nastavení a datová vazba v takovém případě nebude fungovat.
Některé převaděče hodnot jsou napsány speciálně pro konkrétní aplikace, zatímco jiné jsou generalizovány. 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 implicitně 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ů; Převaděč hodnot může 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. Convert
ConvertBack
Argument a parameter
je popsán dále v tomto článku.
Vlastnosti převaděče vazeb
Třídy převaděče hodnot mohou mít vlastnosti a obecné parametry. Tento konkrétní převaděč hodnot převede bool
zdroj na objekt typu T
cíle:
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);
}
}
Stránka Přepnout indikátory ukazuje, jak se dá 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ů, tato stránka ukazuje alternativu: Každý převaděč hodnot je vytvořena instance mezi Binding.Converter
značkami elementů vlastností. Označuje x:TypeArguments
obecný argument a TrueObject
FalseObject
oba jsou nastaveny na objekty tohoto typu:
<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>
V poslední ze tří Switch
a Label
párů je obecný argument nastaven na Style
, a celé Style
objekty jsou k dispozici pro hodnoty TrueObject
a FalseObject
. 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:
Je také možné použít Triggers
k implementaci podobných změn v uživatelském rozhraní na základě jiných zobrazení.
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, aby prováděl poněkud odlišné převody.
Použití ConverterParameter
je demonstrováno pomocí programu pro výběr barev. V tomto případě RgbColorViewModel
má tři vlastnosti typu double
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 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;
}
}
}
Rozsah Red
, Green
a Blue
vlastnosti v rozmezí 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. První dva úkoly (vynásobené číslem 255 a převodem na celé číslo) je možné zpracovat 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 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;
}
}
Převede Convert
z argumentu na double
int
hodnotu a vynásobí hodnotou; ConvertBack
celočíselnou parameter
hodnotu parameter
vydělí value
a vrátí double
výsledek. (V níže uvedeném programu se převaděč hodnot používá pouze v souvislosti s formátováním řetězců, takže ConvertBack
se nepoužívá.)
Typ argumentu parameter
se bude pravděpodobně lišit v závislosti na tom, jestli je datová vazba definovaná v kódu nebo XAML. 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 jazyce XAML se ale ConverterParameter
pravděpodobně nastaví takto:
<Label Text="{Binding Red,
Converter={StaticResource doubleToInt},
ConverterParameter=255,
StringFormat='Red = {0:X2}'}" />
255 vypadá jako číslo, ale protože ConverterParameter
je typu Object
, analyzátor XAML považuje 255 za řetězec.
Z tohoto důvodu převaděč hodnot uvedený výše obsahuje samostatnou GetParameter
metodu, která zpracovává případy parameter
typu double
, int
nebo string
.
Stránka selektoru barev RGB vytvoří DoubleToIntConverter
instanci ve slovníku prostředků podle definice dvou implicitních stylů:
<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>
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í double
hodnotu nastavit na ConverterParameter
vlastnost.
Tady je výsledek: