WPF、Silverlight及Windows Phone程序开发中往往需要将绑定的数据进行特定转换,比如DateTime类型的时间转换为yyyyMMdd的日期,再如有一个值是根据另外多组值的不同而异的,此时我们就需要定制自己的Converter。.Net Framework提供了两种Converter接口,单值转换的接口IValueConverter和多值转换的接口IMultiValueConverter,它们都属于System.Windows.Data命名空间,在程序集PresentationFramework.dll中。这两种值转换器都是分区域性的。其中方法Convert和ConvertBack都具有指示区域性信息的culture参数。如果区域性信息与转换无关,那么在自定义转换器中可以忽略该参数。
将单一值转换为特定类型的值,以日期转换为例如下:
1、定制DateConverter类,其中当值从绑定源传播给绑定目标时,调用方法Convert。
1 public class DateConverter : IValueConverter
2 {
3 public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
4 {
5 return ((DateTime)value).ToString("yyyy/MM/dd");
6 }
7
8 public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
9 {
10 return null;
11 }
12 }
当值从绑定目标传播给绑定源时,调用此方法ConvertBack,方法ConvertBack的实现必须是方法Convert的反向实现。例如下:
1 public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
2 {
3 DateTime date = (DateTime)value;
4 return date.ToShortDateString();
5 }
6
7 public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
8 {
9 string strValue = value as string;
10 DateTime resultDateTime;
11 if (DateTime.TryParse(strValue, out resultDateTime))
12 {
13 return resultDateTime;
14 }
15 return DependencyProperty.UnsetValue;
16 }
返回值DependencyProperty.UnsetValue表示转换器没有生成任何值。但是通常情况下方法ConvertBack没有方法Convert常用,这里不做过多介绍。
2、在xmal文件引用DateConverter类所在命名空间。
1 xmlns:cvt="clr-namespace:ValueConverterDemo.Converter"
3、在xaml文件添加Resources。
1 <Window.Resources>
2 <cvt:DateConverter x:Key="cvtDate"/>
3 </Window.Resources>
4、在xaml文件中指定Binding值的Converter
1 Text="{Binding CurrentDate, Converter={StaticResource cvtDate}}"
效果如下图,图中“时间”是未经过转换的原始DateTime类型,“日期”经过转换处理后只显示日期部分。
将多组值转换为特定类型的值,以纵横流量影响交通指示灯颜色的变化为例如下:
当纵向流量大于横向流量时指示灯应为绿色,当纵向流量小于横向流量时指示灯应为红色,否则指示灯为黄色。
1、定制ColorConverter类,此时Convert中参数是object[] values,values[0]对应MultiBinding中的第一个Binding值,这里是纵向流量值,依此类推,可以在MultiBinding对象中指定多个绑定。
1 public class ColorConverter : IMultiValueConverter
2 {
3 public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
4 {
5 double verValue = (double)values[0];
6 double horValue = (double)values[1];
7 if (verValue > horValue)
8 {
9 return new SolidColorBrush(Colors.Green);
10 }
11 else if (verValue < horValue)
12 {
13 return new SolidColorBrush(Colors.Red);
14 }
15 return new SolidColorBrush(Colors.Yellow);
16 }
17
18 public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
19 {
20 return null;
21 }
22 }
2、3步同单值转换。
4、xmal文件中指定定制的Converter,此时需要使用的MultiBinding来指定多组Binding。
1 <MultiBinding Converter="{StaticResource cvtColor}">
2 <Binding Path="Value" ElementName="slVer"/>
3 <Binding Path="Value" ElementName="slHor"/>
4 </MultiBinding>
效果如下图交通灯的颜色是根据纵向流量和横向流量的关系而变化的。