WPF and Silverlight 学习笔记(二十一):数据绑定值的自定义转换

对于数据绑定,绑定的数据源的值类型和绑定目标的依赖属性的值类型可能会不同,系统提供了一些默认的绑定类型转换,另外也可以由用户自定义这种绑定转换:

DataBinding4

一、定义CLR类型

定义一个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

三、自定义的绑定类型转换

如定义自定义的绑定类型转换,需要定义一个类,对于这个类要求:

  • 实现System.Windows.Data命名空间的IValueConverter接口,这个接口有两个抽象方法,对应两个方向的转换
  • 为此类添加System.Windows.Data命名空间的ValueConversion这个Attribute,指定转换的源类型和目标类型

代码如下:

   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: }
在绑定时,需要在绑定中指明转换的类型Converter

示例代码如下:

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

posted @ 2009-05-05 14:03  龙腾于海  阅读(4698)  评论(3编辑  收藏  举报