深入浅出WPF——如何实现类的Property与标签的Attribute映射
来源:互联网 发布:知乎怎么发文章 编辑:程序博客网 时间:2024/05/21 07:55
深入浅出WPF——如何实现类的Property与标签的Attribute映射
小序:
咳咳,我知道这个标题不太好让人明白。
它的意思是这样——我们知道,用C#代码编写的类也可以在XAML文档里声明实例,声明之后我们可以使用XAML的Attribute对实例的Property进行赋值。但XAML标签的Attribute只能接受string类型的值,如果像int、double这类简单的值还好办,如果是复杂的值呢?我们应该怎么办?
正文:
我们知道,XAML标签会对应一个实例。如果在XAML里初始化实例的属性,我们有两种语法可以选择:
- 直接使用Attribute="Value"的方法
- 属性元素(Property Element)方法
今天我们讨论的核心就是——第一种方法是如何实现的。
先看一个例子。我为一个Grid设置了矢量渐变画刷:
- <Grid>
- <Grid.Background>
- <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
- <GradientStop Offset="0" Color="White"/>
- <GradientStop Offset="0.5" Color="LawnGreen"/>
- <GradientStop Offset="1" Color="White"/>
- </LinearGradientBrush>
- </Grid.Background>
- </Grid>
效果是这样:
请大家注意StartPoint="0,0" EndPoint="1,1这两个Attribute,它们实际上对应的是实例的两个属性。如果查看MSDN,你会发现这两个属性的数据类型是Point而不是String。那么,一个string类型值是如何被转换成Point类型值的呢?
让我们自己动手DIY一个!
首先,我们准备了一个类:
- public class Human
- {
- public string Name { get; set; }
- public Human Child { get; set; }
- }
这个类具有两个属性
- string类型的Name
- Human类型的Child
现在我的期望是,如果我在XAML里这样写:
- <Window.Resources>
- <local:Human x:Key="human" Child="ABC"/>
- </Window.Resources>
则能够为Human实例的Child赋一个Human类型的值,并且Child.Name就是这个字符串的值。
我们先看看直接写行不行……
我在UI上添加了一个按钮button1,并在它的Click事件处理器里写上:
- private void button1_Click(object sender, RoutedEventArgs e)
- {
- Human h = (Human)this.FindResource("human");
- MessageBox.Show(h.Child.Name);
- }
编译没有问题,但在我点击按钮之后程序抛出异常——告诉我Child不存在。那我们应该怎么做呢?
办法是使用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);
- }
- }
有了这个类还不够,还要使用TypeConverterAttribute这个特征类把StringToHumanTypeConverter这个类“粘贴”到作为目标的Human类上。
- [TypeConverterAttribute(typeof(StringToHumanTypeConverter))]
- public class Human
- {
- public string Name { get; set; }
- public Human Child { get; set; }
- }
因为特征类在使用的时候可以省略Attribute这个词,所以我们也可以写成:
- [TypeConverter(typeof(StringToHumanTypeConverter))]
- public class Human
- {
- public string Name { get; set; }
- public Human Child { get; set; }
- }
但这样写,我们需要认清写在方括号里的是TypeConverterAttribute而不是TypeConverter。
完成之后,再次点击按钮,我们想要的结果就出来了!
TO BE CONTINUE...
- 深入浅出WPF——如何实现类的Property与标签的Attribute映射
- 深入浅出WPF——澄清Attribute与Property
- attribute与property的区别?
- Attribute与Property的区别
- Attribute与Property的区别
- Attribute与Property 的翻译区别 Attribute的使用范围
- DOM中Property与Attribute的区别
- Attribute与Property 的翻译区别
- HTML attribute 与 DOM property 的对比
- HTML attribute 与 DOM property 的对比
- HTML attribute 与 DOM property 的区别
- 深入浅出WPF——XAML的优点
- property和attribute的区别
- property和attribute的区别
- Attribute 和 Property 的区别
- Attribute和Property的区别
- attribute和property的区别
- Attribute和Property的总结
- 在C#.net中使用正则表达式检验输入是否为数字
- 学习struts 1x 配置
- MD5碰撞,与用MD5保存密码的安全防范
- MySQL临时表增删的DDL语句是否会提交事务的测试
- 按位异或运算符^
- 深入浅出WPF——如何实现类的Property与标签的Attribute映射
- ORACLE删除表,序列发生器,索引操作
- ACE_InputCDR和ACE_OutputCDR
- 在PHP中执行系统外部命令
- 使用json-lib的JSONObject.toBean( )时碰到的日期属性转换的问题
- 国内3G牌照正式发放 三运营商分获三张牌照
- Spring Web Service自带Demo浅析(二)
- WEB前端工程师应该具备的技能
- 无题----------致那个漂浮的心