准备一个类
public class Human
{
public string Name {get;set;}
public Human ChiId{get;set;}
}
这个类有两个属性
string类型的Name。
Human类型的ChiId
在XAML里这样写
<Window.Resources>
<local:Human x:Key="human" ChiId="ABCD"/>
</Window.Resources>
则能够为Human实例的ChiId属性赋一个Human类型的值,并且ChiId.Name就是这个字符串的值。
我们先看看直接写行不行。 在UI上添加一个按钮button1,并在它的Click事件处理器里写上
private void Button_Click(object sender, RoutedEventArgs e)
{
Human h = (Human)this.FindResource("human");
MessageBox.Show(h.ChiId.Name);
}
编译没有问题,但是点击按钮之后程序抛出异常,告诉ChiId不存在,为什么ChiId不存在?
原因很简单,Human的ChiId属性是Human类型,而XAML代码中的ABCD是字符串,编译器不知道如何把字符串转化为Human实例,应该怎么做?
办法是使用TypeConverter和TypeConverterAttribute这两个类。
首先,我们要从TypeConverter类派生自己的类,并且重写他的一个ConverrtFrom方法,这个方法有一个参数名为value,这个值就是在XAML文档里为它设置的值我们要做的就是把这个值“”翻译成合适类型的值付给对象的属性:
public class StringToHumanTypeConverter : TypeConverter
{
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value is string)
{
Human h = new Human();
h.Name = value as string;
return h;
}
return base.ConvertFrom(context, culture, value);
}
}
完成这个类还不够,还要使用TypeConverterAttribute,这个特征把StringToType
Converter这个类"复制粘贴"到作为目标的Human类上
[TypeConverterAttribute(typeof(StringToHumanTypeConverter))]
public class Human
{
public string Name {get;set;}
public Human ChiId{get;set;}
}
因为特征类在使用的时候可以省略Attribute,所以也可以写成:
[TypeConverter(typeof(StringToHumanTypeConverter))]
public class Human
{
public string Name {get;set;}
public Human ChiId{get;set;}
}
完成之后我们点击按钮,结果就出来了
注:TypeConverter类的使用方法远不只重载一个方法那么简单,为了配合这个方法运行还需要重载其他方法,详细使用方法请参考TypeConverter的类库文档:
TypeConverter 类 (System.ComponentModel) | Microsoft Docs