数据转换(Data Convert)原理
Binding还有另外一种机制称为数据转换( Data Convert),当 Source 端Path所关联的数据与 Target端目标属性数据类型不一致时,我们可以添加数据转换器( Data Converter)。前面的例子中我们都使用 Binding在 Slider控件与 Textbox控件之间建立关联 Slider控件作为 Source(Pah是 Value属性), Textbox控件作为 Target(目标属性为Text)。 Slider的 Value属性是 double类型值、 Textbox的Text属性是 string类型值,在C#这种强类型( strong-typed)语言中却可以往来自如,这是怎么回事呢?实际上是 double类型与 string类型互相转换的问题,因为处理起来比较简单,所以WPF类库就自动替我们做了。但有些类型之间的转换就不是WPF能替我们做的了,例如下面这些情况:
- Source里的数据是Y、N和X三个值(可能是char类型、 string类型或自定义枚举类型)UI上对应的是 Checkbox控件,需要把这三个值映射为它的 Is Checked属性值(bool?类型)。
- 当 textbox里已经输入了文字时用于登录的 Buttonオ会出现,这是 string类型与 Visibility
枚举类型或bool类型之间的转换( Binding的Mode将是 One Way)。 - Source里的数据可能是Male或 Female( string或枚举),UI上对应的是用于显示头像的Image控件,这时候需要把 Source里的值转换成对应的头像图片URI(亦是 One Way)。
当遇到这些情况时,我们只能自己动手写 Converter,方法是创建一个类并让这个类实现IValue Converter接口。 IValueConverter接口定义如下:
public interface IValueConverter
{
object Convert(object value, Type targetType, object parameter, CultureInfo culture);
//
// 摘要:
// 转换值。
//
// 参数:
// value:
// 绑定目标生成的值。
//
// targetType:
// 要转换为的类型。
//
// parameter:
// 要使用的转换器参数。
//
// culture:
// 要用在转换器中的区域性。
//
// 返回结果:
// 转换后的值。 如果该方法返回 null,则使用有效的 null 值。
object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture);
}
**说明:**当数据从 Binding的 Source流向 Target 时, Convert方法将被调用;反之, ConvertBack方法将被调用。这两个方法的参数列表一模一样:第一个参数为 object,最大限度地保证了 Converter的重用性(可以在方法体内对实际类型进行判断);第二个参数用于确定方法的返回类型(个人认为形参名字叫 output Type比 target Type要好,可以避免与 Binding的 Target混淆):第三个参数用于把额外的信息传入方法,若需要传递多个信息则可把信息放入一个集合对象来传入方法。
Binding对象的Mode属性会影响到这两个方法的调用。如果Mode为 Two Way或 Default行为与 Two
Way一致则两个方法都有可能被调用:如果Mode为 One Way或 Default行为与 One Way致则只有
Convert方法会被调用;其他情况同理。
数据转换(Data Convert)示例
首先创建几个自定义数据类型:
public enum Category
{
Ship, Fighter
}
public enum State
{
Available, Locked, Unknown
}
public class Transportation
{
public Category Category {
get; set; }
public string Name {
get; set; }
public State State {
get; set; }
}
在UI里Transportation的 Category,属性被映射为船或飞机的图标,在资源管理器里加入这两个图标。
同时,交通工具的 State属性在UI里被映射为 Checkbox。因为存在以上两个映射关系,我们需要提供两个 Converter:一个是由 Category类型单向转换为 string类型(XAML编译器能够把 string对象解析为图片资源),另一个是在 State与bool?类型之间双向转换。
代码如下:
public class CategoryToSourceConverter :