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>
效果如下圖交通燈的顏色是根據縱向流量和橫向流量的關系而變化的。
- 縱向流量大於橫向流量
- 縱向流量小於橫向流量
- 縱向流量等於橫向流量