Pengikatan pengonversi nilai
Pengikatan data .NET Multi-platform App UI (.NET MAUI) biasanya mentransfer data dari properti sumber ke properti target, dan dalam beberapa kasus dari properti target ke properti sumber. Transfer ini mudah ketika properti sumber dan target memiliki jenis yang sama, atau ketika satu jenis dapat dikonversi ke jenis lain melalui konversi implisit. Ketika itu tidak terjadi, konversi jenis harus terjadi.
Dalam artikel Pemformatan string, Anda melihat bagaimana Anda dapat menggunakan StringFormat
properti pengikatan data untuk mengonversi jenis apa pun menjadi string. Untuk jenis konversi lainnya, Anda perlu menulis beberapa kode khusus di kelas yang mengimplementasikan IValueConverter antarmuka. Kelas yang mengimplementasikan IValueConverter disebut pengonversi nilai, tetapi juga sering disebut sebagai pengikatan pengonversi atau pengikatan pengonversi nilai.
Pengikatan pengonversi nilai
Misalkan Anda ingin menentukan pengikatan data di mana properti sumber berjenis int
tetapi properti target adalah bool
. Anda ingin pengikatan data ini menghasilkan false
nilai ketika sumber bilangan bulat sama dengan 0, dan true
sebaliknya. Ini dapat dicapai dengan kelas yang mengimplementasikan IValueConverter antarmuka:
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;
}
}
Anda kemudian mengatur instans kelas ini ke Converter
properti Binding
kelas atau ke Converter
properti Binding
ekstensi markup. Kelas ini menjadi bagian dari pengikatan data.
Metode Convert
ini dipanggil ketika data berpindah dari sumber ke target dalam OneWay
atau TwoWay
pengikatan. Parameter value
adalah objek atau nilai dari sumber pengikatan data. Metode harus mengembalikan nilai dari jenis target pengikatan data. Metode yang ditunjukkan di sini melemparkan value
parameter ke dan int
kemudian membandingkannya dengan 0 untuk nilai yang bool
dikembalikan.
Metode ConvertBack
ini dipanggil ketika data berpindah dari target ke sumber dalam TwoWay
atau OneWayToSource
pengikatan. ConvertBack
melakukan konversi yang berlawanan: Mengasumsikan value
parameter adalah bool
dari target, dan mengonversinya menjadi nilai pengembalian int
untuk sumber.
Catatan
Jika pengikatan data juga menyertakan StringFormat
pengaturan, pengonversi nilai dipanggil sebelum hasil diformat sebagai string.
Contoh berikut menunjukkan cara menggunakan pengonversi nilai ini dalam pengikatan data:
<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>
Dalam contoh ini, IntToBoolConverter
dibuat dalam kamus sumber daya halaman. Kemudian dirujuk dengan StaticResource
ekstensi markup untuk mengatur Converter
properti dalam dua pengikatan data. Sangat umum untuk berbagi pengonversi data di antara beberapa pengikatan data di halaman. Jika pengonversi nilai digunakan di beberapa halaman aplikasi Anda, Anda dapat membuat instansnya dalam kamus sumber daya tingkat aplikasi.
Contoh ini menunjukkan kebutuhan umum saat Button melakukan operasi berdasarkan teks yang diketik pengguna ke dalam Entry tampilan. Properti Text
masing-masing Entry diinisialisasi ke string kosong, karena Text
properti secara null
default, dan pengikatan data tidak akan berfungsi dalam kasus tersebut. Jika tidak ada yang ditik ke Entrydalam , Button harus dinonaktifkan. Masing-masing Button berisi pengikatan data pada propertinya IsEnabled
. Sumber pengikatan data adalah Length
properti properti Text
dari yang sesuai Entry. Length
Jika properti tersebut bukan 0, pengonversi nilai akan kembali true
dan Button diaktifkan:
Catatan
Jika Anda tahu bahwa pengonversi nilai hanya akan digunakan dalam OneWay
pengikatan, maka ConvertBack
metode hanya dapat mengembalikan null
.
Metode Convert
yang ditunjukkan di atas mengasumsikan bahwa value
argumen berjenis int
dan nilai yang dikembalikan harus berjenis bool
. Demikian pula, ConvertBack
metode mengasumsikan bahwa value
argumen berjenis bool
dan nilai yang dikembalikan adalah int
. Jika tidak demikian, pengecualian runtime akan terjadi.
Anda dapat menulis pengonversi nilai agar lebih umum dan menerima beberapa jenis data yang berbeda. Metode Convert
dan ConvertBack
dapat menggunakan as
operator atau is
dengan parameter , atau dapat memanggil GetType
parameter tersebut value
untuk menentukan jenisnya, dan kemudian melakukan sesuatu yang sesuai. Jenis nilai pengembalian setiap metode yang diharapkan diberikan oleh targetType
parameter . Terkadang, pengonversi nilai digunakan dengan pengikatan data dari berbagai jenis target. Dalam hal ini, pengonversi nilai dapat menggunakan targetType
argumen untuk melakukan konversi untuk jenis yang benar.
Jika konversi yang dilakukan berbeda untuk budaya yang berbeda, gunakan culture
parameter untuk tujuan ini.
Mengikat properti pengonversi
Kelas pengonversi nilai dapat memiliki properti dan parameter generik. Pengonversi nilai berikut mengonversi bool
dari sumber ke objek jenis T
untuk target:
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);
}
}
Contoh berikut menunjukkan bagaimana konverter ini dapat digunakan untuk menampilkan nilai Switch tampilan. Meskipun umum untuk membuat instans pengonversi nilai sebagai sumber daya dalam kamus sumber daya, contoh ini menunjukkan alternatif. Di sini, setiap pengonversi nilai dibuat di antara Binding.Converter
tag elemen properti. x:TypeArguments
menunjukkan argumen generik, dan dan TrueObject
FalseObject
keduanya diatur ke objek jenis tersebut:
<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>
Dalam contoh ini, di terakhir dari tiga Switch pasangan dan Label , argumen generik diatur ke Style, dan seluruh Style objek disediakan untuk nilai TrueObject
dan FalseObject
. Ini mengambil alih gaya implisit untuk Label diatur dalam kamus sumber daya, sehingga properti dalam gaya tersebut Labelsecara eksplisit ditetapkan ke . Mengalihkan Switch penyebab yang sesuai Label untuk mencerminkan perubahan:
Catatan
Dimungkinkan juga untuk menggunakan pemicu untuk menerapkan perubahan di antarmuka pengguna berdasarkan tampilan lain. Untuk informasi selengkapnya, lihat Pemicu.
Mengikat parameter konverter
Kelas Binding
menentukan ConverterParameter
properti, dan Binding
ekstensi markup juga menentukan ConverterParameter
properti. Jika properti ini diatur, maka nilai diteruskan ke Convert
metode dan ConvertBack
sebagai parameter
argumen. Bahkan jika instans pengonversi nilai dibagikan di antara beberapa pengikatan data, ConverterParameter
bisa berbeda untuk melakukan konversi yang berbeda.
Penggunaan ConverterParameter
properti dapat ditunjukkan dengan program pemilihan warna. Contoh berikut menunjukkan RgbColorViewModel
, yang memiliki tiga properti jenis float
bernama Red
, Green
, dan Blue
yang digunakannya untuk membangun Color nilai:
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"));
}
}
}
}
Nilai Red
properti , Green
, dan Blue
dapat berkisar antara 0 dan 1. Namun, Anda mungkin lebih suka komponen ditampilkan sebagai nilai heksadesimal dua digit. Untuk menampilkan ini sebagai nilai heksadesimal di XAML, nilai tersebut harus dikalikan dengan 255, dikonversi menjadi bilangan bulat, lalu diformat dengan spesifikasi "X2" dalam StringFormat
properti . Mengalikan dengan 255 dan mengonversi ke bilangan bulat dapat dilakukan oleh pengonversi nilai. Untuk membuat pengonversi nilai segeneral mungkin, faktor perkalian dapat ditentukan dengan ConverterParameter
properti , yang berarti bahwa ia memasukkan Convert
metode dan ConvertBack
sebagai parameter
argumen:
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;
}
}
Dalam contoh ini, Convert
metode mengonversi dari menjadi int
float
sementara dikalikan parameter
dengan nilai . Metode ConvertBack
membagi argumen bilangan bulat value
dengan parameter
dan mengembalikan hasil float
.
Jenis parameter
argumen kemungkinan berbeda tergantung pada apakah pengikatan data ditentukan dalam XAML atau kode. ConverterParameter
Jika properti diatur Binding
dalam kode, kemungkinan akan diatur ke nilai numerik:
binding.ConverterParameter = 255;
Properti ConverterParameter
berjenis Object
, sehingga pengkompilasi C# menginterpretasikan literal 255 sebagai bilangan bulat, dan mengatur properti ke nilai tersebut.
Namun, di XAML ConverterParameter
kemungkinan akan diatur seperti ini:
<Label Text="{Binding Red,
Converter={StaticResource doubleToInt},
ConverterParameter=255,
StringFormat='Red = {0:X2}'}" />
Sementara 255 terlihat seperti angka, karena ConverterParameter
berjenis Object
, pengurai XAML memperlakukan 255 sebagai string. Untuk alasan ini, pengonversi nilai menyertakan metode terpisah GetParameter
yang menangani kasus karena parameter
jenis float
, , int
atau string
.
Contoh XAML berikut membuat instans FloatToIntConverter
dalam kamus sumber dayanya:
<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>
Nilai Red
properti dan Green
ditampilkan dengan Binding
ekstensi markup. Properti Blue
, bagaimanapun, membuat instans Binding
kelas untuk menunjukkan bagaimana nilai eksplisit float
dapat diatur ke ConverterParameter
properti: