深入浅出WPF——如何实现类的Property与标签的Attribute映射

简介:
小序:
咳咳,我知道这个标题不太好让人明白。
它的意思是这样——我们知道,用C#代码编写的类也可以在XAML文档里声明实例,声明之后我们可以使用XAML的Attribute对实例的 Property进行赋值。但XAML标签的Attribute只能接受string类型的值,如果像int、double这类简单的值还好办,如果是复 杂的值呢?我们应该怎么办?
 
正文:
我们知道,XAML标签会对应一个实例。如果在XAML里初始化实例的属性,我们有两种语法可以选择:
  • 直接使用Attribute="Value"的方法
  • 属性元素(Property Element)方法
今天我们讨论的核心就是——第一种方法是如何实现的。
先看一个例子。我为一个Grid设置了矢量渐变画刷:
  1.     <Grid>
  2.         <Grid.Background>
  3.             <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
  4.                 <GradientStop Offset="0" Color="White"/>
  5.                 <GradientStop Offset="0.5" Color="LawnGreen"/>
  6.                 <GradientStop Offset="1" Color="White"/>
  7.             </LinearGradientBrush>
  8.         </Grid.Background>
  9.     </Grid>
效果是这样:
 
请大家注意 StartPoint = "0,0"   EndPoint = "1,1这两个Attribute,它们实际上对应的是实例的两个属性。如果查看MSDN,你会发现这两个属性的数据类型是Point而不是String。那么,一个string类型值是如何被转换成Point类型值的呢?
 
让我们自己动手DIY一个!
 
首先,我们准备了一个类:
 
  1.     public class Human
  2.     {
  3.         public string Name { getset; }
  4.         public Human Child { getset; }
  5.     }
这个类具有两个属性
  • string类型的Name
  • Human类型的Child
现在我的期望是,如果我在XAML里这样写:
  1.     <Window.Resources>
  2.         <local:Human x:Key="human" Child="ABC"/>
  3.     </Window.Resources>
则能够为Human实例的Child赋一个Human类型的值,并且Child.Name就是这个字符串的值。
我们先看看直接写行不行……
我在UI上添加了一个按钮button1,并在它的Click事件处理器里写上:
  1.         private void button1_Click(object sender, RoutedEventArgs e)
  2.         {
  3.             Human h = (Human)this.FindResource("human");
  4.             MessageBox.Show(h.Child.Name);
  5.         }
编译没有问题,但在我点击按钮之后程序抛出异常——告诉我Child不存在。那我们应该怎么做呢?
办法是使用TypeConverter和TypeConverterAttribute这两个类。
 
首先,我们要从TypeConverter类派生出自己的类,并重写它的一个ConvertFrom方法。这个方法有一个参数名为value,这个值就是在XAML文档里为它设置的值。我们要做的就是把这个值“翻译”成合适类型的值、赋给对象的属性:
  1.     public class StringToHumanTypeConverter : TypeConverter
  2.     {
  3.         public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
  4.         {
  5.             if (value is string)
  6.             {
  7.                 Human h = new Human();
  8.                 h.Name = value as string;
  9.                 return h;
  10.             }
  11.             return base.ConvertFrom(context, culture, value);
  12.         }
  13.     }
有了这个类还不够,还要使用TypeConverterAttribute这个特征类把StringToHumanTypeConverter这个类“粘贴”到作为目标的Human类上。
  1.     [TypeConverterAttribute(typeof(StringToHumanTypeConverter))]
  2.     public class Human
  3.     {
  4.         public string Name { getset; }
  5.         public Human Child { getset; }
  6.     }
因为特征类在使用的时候可以省略Attribute这个词,所以我们也可以写成:
  1.     [TypeConverter(typeof(StringToHumanTypeConverter))]
  2.     public class Human
  3.     {
  4.         public string Name { getset; }
  5.         public Human Child { getset; }
  6.     }
但这样写,我们需要认清写在方括号里的是TypeConverterAttribute而不是TypeConverter。
 
完成之后,再次点击按钮,我们想要的结果就出来了!
 
 
 
TO BE CONTINUED...








本文转自 水之真谛 51CTO博客,原文链接:http://blog.51cto.com/liutiemeng/129502,如需转载请自行联系原作者
目录
相关文章
|
C# 前端开发 数据安全/隐私保护
WPF QuickStart系列之附加属性(Attached Property)
原文:WPF QuickStart系列之附加属性(Attached Property) 这一篇博客是关于如何使用附加属性和创建自定义附加属性的。 1. 附加属性使用, WPF中对附加属性使用最多的莫过于对控件布局时设置控件的位置,例如在Canvas中有一个Rectangle, Ellipse, ...
1030 0
|
7月前
|
C# 开发者 Windows
基于Material Design风格开源、易用、强大的WPF UI控件库
基于Material Design风格开源、易用、强大的WPF UI控件库
403 0
|
7月前
|
C#
浅谈WPF之装饰器实现控件锚点
使用过visio的都知道,在绘制流程图时,当选择或鼠标移动到控件时,都会在控件的四周出现锚点,以便于修改大小,移动位置,或连接线等,那此功能是如何实现的呢?在WPF开发中,想要在控件四周实现锚点,可以通过装饰器来实现,今天通过一个简单的小例子,简述如何在WPF开发中,应用装饰器,仅供学习分享使用,如有不足之处,还请指正。
155 1
|
4月前
|
开发框架 缓存 前端开发
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(11) -- 下拉列表的数据绑定以及自定义系统字典列表控件
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(11) -- 下拉列表的数据绑定以及自定义系统字典列表控件
|
4月前
|
C# 开发者 Windows
一款基于Fluent设计风格、现代化的WPF UI控件库
一款基于Fluent设计风格、现代化的WPF UI控件库
120 1
|
4月前
|
C# Windows
WPF中如何使用HandyCotrol控件库
WPF中如何使用HandyCotrol控件库
214 1
|
4月前
|
C# 前端开发 UED
WPF数据验证实战:内置控件与自定义规则,带你玩转前端数据验证,让你的应用程序更上一层楼!
【8月更文挑战第31天】在WPF应用开发中,数据验证是确保输入正确性的关键环节。前端验证能及时发现错误,提升用户体验和程序可靠性。本文对比了几种常用的WPF数据验证方法,并通过示例展示了如何使用内置验证控件(如`TextBox`)及自定义验证规则实现有效验证。内置控件结合`Validation`类可快速实现简单验证;自定义规则则提供了更灵活的复杂逻辑支持。希望本文能帮助开发者更好地进行WPF数据验证。
154 0