对于数据绑定,绑定的数据源的值类型和绑定目标的依赖属性的值类型可能会不同,系统提供了一些默认的绑定类型转换,另外也可以由用户自定义这种绑定转换:
定义一个CLR类型,内部存在两个属性字符串类型的ColorString和Color对象类型的ColorObject,供应用程序界面调用:
1: using System.ComponentModel;
2: using System.Windows.Media;
3:
4: namespace BasicWPFDataBinding
5: {
6: public class MyBindingColor : INotifyPropertyChanged
7: {
8: public event PropertyChangedEventHandler PropertyChanged;
9:
10: public MyBindingColor()
11: {
12: _ColorString = "Red";
13: _ColorObject = Colors.Red;
14: }
15:
16: // 字符串类型的ColorString
17: private string _ColorString;
18: public string ColorString
19: {
20: set
21: {
22: _ColorString = value;
23: if (PropertyChanged != null)
24: {
25: PropertyChanged(this,new PropertyChangedEventArgs("ColorString"));
26: }
27: }
28: get
29: {
30: return _ColorString;
31: }
32: }
33:
34: // Color对象类型的ColorObject
35: private Color _ColorObject;
36: public Color ColorObject
37: {
38: set
39: {
40: _ColorObject = value;
41: if (PropertyChanged != null)
42: {
43: PropertyChanged(this, new PropertyChangedEventArgs("ColorObject"));
44: }
45: }
46: get
47: {
48: return _ColorObject;
49: }
50: }
51: }
52: }
系统定义了一系列的常用的绑定的数据类型转换,例如可以由字符串(String)型和SolidColorBrush对象间相互转换。字符串与SolidColorBrush的转换规则有两种,一种是对应命名的颜色,如Red、Green、Blue等,另一种是#AARRGGBB或#RRGGBB组成的RGB颜色或ARGB颜色。
例如,下面的示例将字符串类型的ColorString属性绑定到Rectangle的Brush类型的Fill属性上(SolidColorBrush是Brush的子类,可以自动转换)。
XAML代码如下:
1: <StackPanel Grid.Row="0" Grid.Column="0" x:Name="panelBindingColorString">
2: <StackPanel.Resources>
3: <c:MyBindingColor x:Key="myDataSourceA" />
4: </StackPanel.Resources>
5: <StackPanel.DataContext>
6: <Binding Source="{StaticResource myDataSourceA}" />
7: </StackPanel.DataContext>
8: <TextBlock Margin="5" Text="Binding Fill To String" />
9: <Rectangle Margin="5" Height="30"
10: Fill="{Binding Path=ColorString}" />
11: <TextBox Margin="5" x:Name="txtValueA" />
12: <Button Margin="5" Content="Change Fill"
13: x:Name="btn_ChangeColorString" Click="btn_ChangeColorString_Click" />
14: <Button Margin="5" Content="Get Fill"
15: x:Name="btn_GetColorString" Click="btn_GetColorString_Click" />
16: </StackPanel>
CS代码如下:
1: #region 利用系统自带的字符串向SolidColorBrush对象的转换实现绑定
2: private void btn_ChangeColorString_Click(object sender, RoutedEventArgs e)
3: {
4: try
5: {
6: MyBindingColor source = (MyBindingColor)(panelBindingColorString.DataContext);
7: source.ColorString = txtValueA.Text;
8: }
9: catch (Exception ex)
10: {
11: MessageBox.Show(
12: ex.Message,
13: "System Information",
14: MessageBoxButton.OK,
15: MessageBoxImage.Error);
16: }
17:
18: }
19:
20: private void btn_GetColorString_Click(object sender, RoutedEventArgs e)
21: {
22: MyBindingColor source = (MyBindingColor)(panelBindingColorString.DataContext);
23:
24: MessageBox.Show(
25: string.Format("The Binding ColorString to {0}.", source.ColorString),
26: "System Information",
27: MessageBoxButton.OK,
28: MessageBoxImage.Information);
29: }
30: #endregion
如定义自定义的绑定类型转换,需要定义一个类,对于这个类要求:
代码如下:
1: using System;
2: using System.Windows.Data;
3: using System.Windows.Media;
4:
5: namespace BasicWPFDataBinding
6: {
7: /// <summary>
8: /// 自定义的由Color对象向SolidColorBrush对象进行转换
9: /// </summary>
10: [ValueConversion(typeof(Color),typeof(SolidColorBrush))]
11: public class MyColorConverter : IValueConverter
12: {
13: #region IValueConverter Members
14:
15: // 由Color对象向SolidColorBrush对象转换
16: public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
17: {
18: Color val = (Color) (value);
19: return new SolidColorBrush(val);
20: }
21:
22: // 由SolidColorBrush对象向Color对象转换
23: public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
24: {
25: SolidColorBrush brush = (SolidColorBrush) value;
26: return brush.Color;
27: }
28:
29: #endregion
30: }
31: }
示例代码如下:
XAML代码:
1: <StackPanel Grid.Row="1" Grid.Column="0" x:Name="panelBindingColorObject">
2: <StackPanel.Resources>
3: <c:MyBindingColor x:Key="myDataSourceB" />
4: <c:MyColorConverter x:Key="myConverter" />
5: </StackPanel.Resources>
6: <StackPanel.DataContext>
7: <Binding Source="{StaticResource myDataSourceB}" />
8: </StackPanel.DataContext>
9: <TextBlock Margin="5" Text="Binding Fill To Color" />
10: <Rectangle Margin="5" Height="30"
11: Fill="{Binding Path=ColorObject, Converter={StaticResource myConverter}}" />
12: <TextBox Margin="5" x:Name="txtValueB" />
13: <Button Margin="5" Content="Change Fill"
14: x:Name="btn_ChangeColorObject" Click="btn_ChangeColorObject_Click" />
15: <Button Margin="5" Content="Get Fill"
16: x:Name="btn_GetColorObject" Click="btn_GetColorObject_Click" />
17: </StackPanel>
CS代码:
1: #region 使用自定义的由Color对象向SolidColorBrush对象进行转换
2: private void btn_ChangeColorObject_Click(object sender, RoutedEventArgs e)
3: {
4: try
5: {
6: MyBindingColor source = (MyBindingColor)(panelBindingColorObject.DataContext);
7:
8: string txt = txtValueB.Text;
9: string[] items = txt.Split(',');
10:
11: Color clr = Colors.Black;
12: if (items.Length == 3)
13: {
14: byte r = byte.Parse(items[0], NumberStyles.HexNumber);
15: byte g = byte.Parse(items[1], NumberStyles.HexNumber);
16: byte b = byte.Parse(items[2], NumberStyles.HexNumber);
17:
18: clr = Color.FromRgb(r, g, b);
19: }
20: else if (items.Length == 4)
21: {
22: byte a = byte.Parse(items[0], NumberStyles.HexNumber);
23: byte r = byte.Parse(items[1], NumberStyles.HexNumber);
24: byte g = byte.Parse(items[2], NumberStyles.HexNumber);
25: byte b = byte.Parse(items[3], NumberStyles.HexNumber);
26:
27: clr = Color.FromArgb(a, r, g, b);
28: }
29:
30: source.ColorObject = clr;
31: }
32: catch (Exception ex)
33: {
34: MessageBox.Show(
35: ex.Message,
36: "System Information",
37: MessageBoxButton.OK,
38: MessageBoxImage.Error);
39: }
40: }
41:
42: private void btn_GetColorObject_Click(object sender, RoutedEventArgs e)
43: {
44: MyBindingColor source = (MyBindingColor)(panelBindingColorObject.DataContext);
45: Color clr = source.ColorObject;
46:
47: string txt = string.Format(
48: "Color ARGB Value is ({0:X},{1:X},{2:X},{3:X}).",
49: clr.A, clr.R, clr.G, clr.B);
50:
51: MessageBox.Show(
52: txt,
53: "System Information",
54: MessageBoxButton.OK,
55: MessageBoxImage.Information);
56: }
57: #endregion