Xamarin.Forms Bağlama Değeri Dönüştürücüleri
Veri bağlamaları genellikle bir kaynak özelliğinden hedef özelliğe ve bazı durumlarda hedef özelliğinden 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. (Evrensel Windows Platformu ad alanında Windows.UI.Xaml.Data
adlı IValueConverter
benzer bir sınıf içerir, ancak bu IValueConverter
ad alanındadırXamarin.Forms
.) 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.
IValueConverter Arabirimi
Kaynak özelliğin türünde int
olduğu ancak hedef özelliğin bir bool
olduğ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.
Bunu, arabirimini uygulayan IValueConverter
bir sınıfla yapabilirsiniz:
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 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.
Veri bağlama bir StringFormat
ayar da içeriyorsa, sonuç dize olarak biçimlendirilmeden önce değer dönüştürücüsü çağrılır.
Örnekteki Düğmeleri Etkinleştir sayfası, bu değer dönüştürücüsunun bir veri bağlamasında nasıl kullanılacağını gösterir. IntToBoolConverter
, sayfanın kaynak sözlüğünde örneği 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:
<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ği oluşturabilirsiniz.
Düğmeleri Etkinleştir sayfası, 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
gereksinim gösterir. 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:
Her Entry
bir içindeki özelliğinin Text
boş bir dizeye başlatıldığına dikkat edin. Text
özelliği varsayılan olarakdır null
ve bu durumda veri bağlama çalışmaz.
Bazı değer dönüştürücüleri özel olarak belirli uygulamalar için yazılırken, diğerleri genelleştirilir. 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
.
Convert
Yukarıda gösterilen yöntem, bağımsız değişkenin value
türünde olduğunu ve dönüş değerinin türünde int
bool
olması gerektiğini örtük olarak varsayar. Benzer şekilde, ConvertBack
yöntemi bağımsız değişkenin value
türünde bool
ve dönüş değerinin olduğunu int
varsayar. 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 kullanılır; değer dönüştürücüsü, doğru tür için bir 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. parameter
ve ConvertBack
bağımsız değişkeni Convert
bu makalenin devamında ele alınmalıdır.
Bağlayıcı Dönüştürücü Özellikleri
Değer dönüştürücü sınıflarının özellikleri ve genel parametreleri olabilir. Bu belirli 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 { 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);
}
}
Göstergeleri Değiştir sayfası, bir Switch
görünümün değerini görüntülemek için nasıl kullanılabileceğini gösterir. Değer dönüştürücülerinin kaynak sözlüğünde kaynak olarak örneğini oluşturmak yaygın olsa da, bu sayfada bir alternatif gösterilmektedir: Her değer dönüştürücüsü, özellik öğesi etiketleri arasında Binding.Converter
örneklenir. 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://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 Label
çiftinin son kısmında genel bağımsız değişken olarak Style
ayarlanır ve ve FalseObject
değerleri TrueObject
için tüm Style
nesneler 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 Label
atanır. geçişini yapmak Switch
, karşılık gelenin Label
değişikliği yansıtmasına neden olur:
Kullanıcı arabiriminde diğer görünümlere göre benzer değişiklikler uygulamak için de kullanabilirsiniz Triggers
.
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
değeri biraz farklı dönüştürmeler gerçekleştirmek için farklı olabilir.
kullanımı ConverterParameter
bir renk seçimi programıyla gösterilir. Bu durumda , RgbColorViewModel
adlı Green
Red
türünde double
üç özelliği vardır ve Blue
bir Color
değer oluşturmak için bunu kullanı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ö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. İlk iki görev (255 ile çarpılarak ve tamsayıya dönüştürülerek) değer dönüştürücüsü tarafından işlenebilir. 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 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;
}
}
değeriyle Convert
çarparken parameter
a'dan int
double
değerine dönüştürür; ConvertBack
tamsayı value
bağımsız değişkenini ile parameter
böler 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çimlendirmesiyle bağlantılı olarak kullanılır, bu nedenle ConvertBack
kullanılmaz.)
Bağımsız değişkenin türü, veri bağlamanın parameter
kodda mı yoksa XAML'de mi 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 Object
olduğundan, C# derleyicisi değişmez değeri 255'i tamsayı olarak yorumlar ve özelliği bu değere ayarlar.
Ancak ConverterParameter
XAML'de şu şekilde ayarlanmış olabilir:
<Label Text="{Binding Red,
Converter={StaticResource doubleToInt},
ConverterParameter=255,
StringFormat='Red = {0:X2}'}" />
255 bir sayı gibi görünür, ancak türünden Object
dolayı ConverterParameter
XAML ayrıştırıcısı 255'i dize olarak ele alır.
Bu nedenle, yukarıda gösterilen değer dönüştürücüsü , veya türünde olması için parameter
servis taleplerini işleyen ayrı GetParameter
bir yöntem içerir.double
string
int
RGB Renk Seçici sayfası, iki örtük stilin tanımından sonra kaynak sözlüğünde örnek DoubleToIntConverter
olarak gösterilir:
<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 Green
özelliklerinin değerleri Red
bir Binding
işaretleme uzantısıyla görüntülenir. Blue
Ancak özelliği, açık double
bir değerin özelliğine nasıl ayarlanabileceğini Binding
göstermek için sınıfını ConverterParameter
başlatır.
Sonuç şu şekildedir: