1) WPF的xaml文件如下:
<Window x:Class="Chaper3.Page19.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Chaper3.Page19"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:Human x:Key="human" Child="ABC"/>
</Window.Resources>
<Grid>
<Button Click="Button_Click"/>
</Grid>
</Window>
2) 后台代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Chaper3.Page19
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Human h = (Human)this.FindResource("human");
MessageBox.Show(h.Child.Name);
}
}
}
3) 我们的目的是在点击按钮的时候,会弹出Human实例的Child属性的Name属性值,也就是弹出“ABC”,但是这里有个问题是,我们的Human类的Child属性的返回值是Human类型的,所以这就导致我们的h.Child.Name是会出现异常的。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
namespace Chaper3.Page19
{
//使用TypeConverterAttribute特征类把StringToHumanTypeConverter这个类“粘贴”到作为目标的Human类上
//[TypeConverterAttribute(typeof(StringToHumanTypeConverter))]
//因为特征类在使用的时候可以省略Attribute这个词,所以也可以写成
[TypeConverter(typeof(StringToHumanTypeConverter))]
// 这句话的意思是当有其他类或方法给Human类的实例赋值或取值的时候,我们所绑定好的StringToHumanTypeConverter类就是来进行一个类型转换的工作,穿进去的是value,返回的是转换后的值。
public class Human
{
public string Name { get; set; }
public Human Child { get; set; }
}
}
4) 这个时候我们需要使用到TypeConverter类,重写这个类的ConvertFrom方法,让传进来的参数Value转换成我们所希望的值在返回回去:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
namespace Chaper3.Page19
{
//编译没问题,但是点击按钮之后程序会抛出异常,Child不存在。Human的Child属性是Human类型,
//而XAML代码中的ABC是字符串,编译器不知道如何把一个字符串实例转换成一个Human实例。
//这里我们使用TypeConverter和TypeConverterAttribute这两个类。
//首先我们要从TypeConverter类派生出自己的类,并重写它的一个ConvertFrom方法。
//这个方法有一个参数名为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);
}
}
}
5) 在定义完这个类后,需要在需要转换的类上进行Attribute特性的标记,请看上面的Human类里面的[TypeConverter]里的代码。
6) 这个时候我们在点击这个按钮的话就可以直接弹出"ABC"了,因为我们这里先进行了类型转换,把Human类的Child属性返回值转换成了String类型并赋给了Human.Child属性。
源代码: http://download.youkuaiyun.com/detail/eric_k1m/6511491