Có những trường hợp bạn cần thực hiện một binding phức tạp như chuyển đổi, tính toán, tìm kiếm từ giá trị này sang giá trị khác. Để làm được điều này, bạn cần tạo một lớp converter hiện thực interface IValueConverter và gán thể hiện của lớp này cho property Binding.Converter.
Giới thiệu
Interface IValueConverter bao gồm hai phương thức là Convert() và ConvertBack() để chuyển đổi qua lại giữa binding source và binding target. Thông thường bạn chỉ cần hiện thực phương thức Convert() để chuyển từ binding source sang binding target, đối với những trường hợp sử dụng binding mode là TwoWay hay OneWayToSource mới cần hiện thực phương thức ConvertBack(). – Đối với các trường hợp không thể chuyển được giá trị, bạn nên trả về giá trị DependencyProperty.UnsetValue. – Đối với các lớp converter, bạn nên dùng [ValueConversionAttribute] để xác định kiểu dữ liệu sử dụng cho việc chuyển đổi.
Phương thức IValueConverter.Convert
Cú pháp
Object Convert(
Object value,
Type targetType,
Object parameter,
CultureInfo culture
)
Tham số
- value: Giá trị cần chuyển đổi lấy từ binding source.
- targetType: Kiểu dữ liệu của binding target property.
- parameter: Tham số cần thiết
- culture: để áp dụng định dạng với mỗi nền văn hóa khác nhau.
Giá trị trả về
Kết quả của việc chuyển đối.
Ví dụ 1
Ví dụ sau thực hiện một binding hai chiều để chuyển (tính toán) một số thành căn bậc hai của nó và ngược lại.
XAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
xmlns:local = "clr-namespace:WpfApplication1"
Title = "SquareRootConverter Demo" Height = "300" Width = "400" >
< Window.Resources >
< local:SquareRootConverter x:Key = "mySquareRootConverter" />
</ Window.Resources >
< StackPanel >
< TextBox x:Name = "textBox1" />
< Label Content = "Square Root:" />
< TextBox Text = "{Binding ElementName=textBox1, Path=Text, UpdateSourceTrigger=PropertyChanged, Converter= {StaticResource mySquareRootConverter}}" />
</ StackPanel >
</ Window >
|
C# (code-behind):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
[ValueConversion( typeof ( double ), typeof ( double ))]
public class SquareRootConverter : IValueConverter
{
public object Convert( object value, Type targetType, object parameter, CultureInfo culture)
{
double number;
if ( double .TryParse(value.ToString(), out number))
{
return Math.Sqrt(number);
}
return DependencyProperty.UnsetValue;
}
public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture)
{
double number;
if ( double .TryParse(value.ToString(), out number))
{
return number*number;
}
return DependencyProperty.UnsetValue;
}
}
|
Ví dụ 2
Converter mặc định của WPF có thể tự động chuyển đổi từ nhiều kiểu dữ liệu khác nhau, ví dụ như kiểu string trong property TextBox.Text có thể được chuyển thành kiểu Brush cho property StackPanel.Background.
XAML:
1
2
3
4
5
6
7
8
9
10
|
< Window x:Class = "WpfApplication1.Window1"
Title = "StringColorConverter Demo"
Height = "300" Width = "300" >
< StackPanel Background = "{Binding ElementName=txtColor, Path=Text}" >
< TextBox x:Name = "txtColor" >Green</ TextBox >
< Label Content = "{Binding ElementName=txtColor, Path=Text}" />
</ StackPanel >
</ Window >
|
Ví dụ 3
Để thực hiện chuyển đổi sang nhiều kiểu dữ liệu khác nhau, bạn cần phải sử dụng tham sốtargetType của phương thức Convert(). Ví dụ sau thực hiện chuyển một chuỗi tên màu sắc (tiếng Anh) sang Brush hoặc tên màu sắc (tiếng Việt) dựa vào tham số targetType này:
XAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
< Window x:Class = "WpfApplication1.Window1"
xmlns:local = "clr-namespace:WpfApplication1"
Title = "StringColorConverter Demo"
Height = "300" Width = "300" >
< Window.Resources >
< local:StringColorConverter x:Key = "myStringColorConverter" />
</ Window.Resources >
< StackPanel Background = "{Binding ElementName=txtColor, Path=Text,Converter={StaticResource myStringColorConverter}}" >
< TextBox x:Name = "txtColor" >Green</ TextBox >
< Label Content = "{Binding ElementName=txtColor, Path=Text,Converter={StaticResource myStringColorConverter}}" />
< TextBox Text = "{Binding ElementName=txtColor, Path=Text,Converter={StaticResource myStringColorConverter}}" />
</ StackPanel >
</ Window >
|
C# (code-behind):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
public class StringColorConverter:IValueConverter
{
public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (targetType == typeof ( string ))
{
string str = value as string ;
if (str== "Red" )
return "Đỏ" ;
else if (str== "Green" )
return "Xanh lá" ;
else if (str== "Blue" )
return "Xanh biển" ;
else
return "Không biết" ;
}
else if (targetType == typeof (Brush))
{
string str = value as string ;
try
{
Color color= (Color)ColorConverter.ConvertFromString(str);
return new SolidColorBrush(color);
}
catch
{
return DependencyProperty.UnsetValue;
}
}
else
return "DependencyProperty.UnsetValue" ; // return DependencyProperty.UnsetValue;
}
public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
|