其实我一直很好奇在xaml中,通过Attribute=Value这种方式可以进行对元素的描述,

例如:

<Rectangle Name=” rectangle” Fill=”Blue”/>

这是一个矩形,并且利用蓝色来填充。我们知道在wpf中给UI元素上色可以用Brush(画刷),在MSDN中得知Rectangle.Fill就是一个Brush类型。

Brush类的派生类有很多,如下:

  1. SolidColorBrush单色画刷
  2. LinearGradientBrush线性渐变画刷
  3. ImageBrush位图画刷
  4. 其他

这里只列举了三种

我们知道Fill=”Blue”中的Blue只是一个字符串,但它最终被翻译成一个SolidColorBrush并赋值给了Rectangle,用c#描述是这样的:

SolidColorBrush sBrush = new SolidColorBrush();

sBrush.Color=Colors.Blue;

this.rectangle.Fill=sBrush;

由于Xaml的语法限制,这里的Value只可能是字符串,重点来了。这里引出了几个问题:

  1. 如果一个类使用Xaml语言声明,并允许它的Property(属性)与Xaml标签的Attribute(特征)互相映射,那就需要为这些Property添加一个转换机制
  2. 由于Value是字符串类型,所以它的格式复杂程度有限,尽管可以在转换机制里面包含一定的按格式解析字符串的功能以便转换成复杂的目标对象,但这会让最终的XAML使用者头疼不已。因为他们不得不在没有编码辅助的情况下手写一个格式复杂的字符串以满足赋值要求

第一个问题可以通过TypeConvert类的派生类,在派生类重写TypeConverter的一些方法,第二个问题的解决方法就是使用属性元素(PropertyElement)

先看个例子:

public class Human

{

public string Name{get;set;}

pubic Human Child{get;set;}
}

Human类中Name是字符串类型,Child是Human类型

假设我在Xaml这样写:

<Window.Resources>

       <local:Human x:Key=”human” Child=”AAA”/>

</ Window.Resources >

我对Child赋了一个字符串类型,我期望的是Child的Name属性的值是AAA,下面我们来看一下这个Child究竟会发生什么情况。

Human h=(Human)this.FindResources(“human”);

MessageBox.Show(h.Child.Name);

编译没问题,但当运行时程序会抛出异常,Child为null。很明显编译器不懂如何把一个字符串转换成一个Human实例,我们应该怎么办呢?下面终于轮到我们提及的TypeConvert出场了。看代码,我们先从TypeConvert派生一个类StringToHumanTypeConvert。

public class StringToHumanTypeConvert: TypeConvert
{
public overrid object ConvertFrom(ItypeDescriptorContext context,
System.Globalization.CultrueInfo culture,object value)
{
If(value is string)
{
Human h=new Human();
h.Name=value as string;
return h;
}
return base.ConvertFrom(context,culture,value);
}
}

我们重写了它的一个方法ConvertFrom,这个方法有一个参数名为value,这个值就是在Xaml文档里为它设置的值我们要做的就是把这个值”翻译成合适类型的值赋给对象的属性。完成了转换过程,我们需要把这个转换绑到Human类上面,可以使用TypeConvertAttribute这个特征

[TypeConvertAttribute(typeof(StringToHumanTypeConvert))]
public class Human
{
public string Name{get;set;}
pubic Human Child{get;set;}
}

凡是特征类都可以省略Attribute这个词,所以上面的代码可以简写成

[TypeConvert
(typeof(StringToHumanTypeConvert))]

需要注意这里的TypeConvert是一个特征,它的全名是TypeConvertAttribute,他并不是TypeConvert类。

TypeConvert类的使用远远不只重在一个ConvertFrom方法那么简单,为了配合这个方法的运行,还需要重在其他的几个方法。详细使用请自行查阅MSDN。

这里只提到第一个问题是怎样实现,第二个问题怎样解决会在下次说明。大部分知识都是在《深入浅出WPF》一书中整理,最近在学习WPF控件编程,这些知识都是很有用。

Wpf之Xaml属性值和特性值(一)的更多相关文章

  1. WPF动画之后属性值无法改变

    原文:WPF动画之后属性值无法改变         前一段时间使用WPF写2048游戏的时候,遇到下面的情形:使用按键对色块进行移动时,触发位置左边X和Y属性的DoubleAnimation动画,但是 ...

  2. WPF当属性值改变时利用PropertyChanged事件来加载动画

    在我们的程序中,有时我们需要当绑定到UI界面上的属性值发生变化从而引起数据更新的时候能够加载一些动画,从而使数据更新的效果更佳绚丽,在我们的程序中尽量将动画作为一种资源放在xaml中,而不是在后台中通 ...

  3. XAML属性赋值转换之谜(WPF XAML语法解密)

    XAML与XML类似,就是XML延伸过来的.为了更好的表达一些功能,WPF对XML做了扩展,有些功能是WPF在后台悄悄的替你做了.有时候,虽然实现了某个功能,但是对实现原理还是很茫然.今天就讲讲XAM ...

  4. WPF依赖属性值源(BaseValueSource)

    原文:WPF依赖属性值源(BaseValueSource)   WPF依赖属性提供一个机制,可以获取依赖属性提供值的来源 其以BaseValueSource枚举表示 1.Default public ...

  5. [WPF系列]-数据邦定之DataTemplate 使用 DataTrigger 来应用属性值

    使用 DataTrigger 来应用属性值 当前表示不会告诉我们某个 Task 是家庭任务还是办公室任务.记住 Task 对象拥有类型为 TaskType 的 TaskType 属性,该类型是一个枚举 ...

  6. WPF入门:XAML

    XAML是WPF技术中专门用于设计UI的语言 XAML优点最大的优点是将UI与逻辑代码剥离 创建第一个WPF应用程序 VS默认生成的WPF项目解决方案 Properties:里面主要包含了程序用到的一 ...

  7. WPF DataGrid常用属性记录

    WPF DataGrid常用属性记录 组件常用方法: BeginEdit:使DataGrid进入编辑状态. CancelEdit:取消DataGrid的编辑状态. CollapseRowGroup:闭 ...

  8. [转]WPF 依赖项属性

    from:http://blog.csdn.net/datoumimi/article/details/8033682 ps:环境限制,发的东西一长就会被拦截,所以删了一部分 UI软件中经常会用到大量 ...

  9. WPF利用依赖属性和命令编写自定义控件

    以实例讲解(大部分讲解在代码中) 1,新建一个WPF项目,添加一个用户控件之后在用户控件里面添加几个控件用作测试, <UserControl x:Class="SelfControlD ...

随机推荐

  1. JSON总结

    JSON:  关于JSON,最重要的是要理解它是一种数据格式,不是一种编程语言.虽然JSON与JavaScript具有相同的语法形式与JSON具有相同的语法形式,但JSON并不从属于JavaScrip ...

  2. java性能监控常用命令

    jps -m -l:主要用来输出JVM中运行的进程状态信息 jstack -l pid 来观察锁持有情况 jsatck pid | grep pid(十六进制):输出进程pid的堆栈信息 jmap - ...

  3. Codeforces Round #389 (Div. 2, Rated, Based on Technocup 2017 - Elimination Round 3) C

    Description Santa Claus has Robot which lives on the infinite grid and can move along its lines. He ...

  4. angular的$scope

    angularJS是一个MVVM的前端js框架. $scope的作用是angular向视图(html)传递数据的通道,它不负责处理和操作数据.也就是说要想向视图传递数据的话,必须定义$scope变量. ...

  5. 如何在R语言中使用Logistic回归模型

    在日常学习或工作中经常会使用线性回归模型对某一事物进行预测,例如预测房价.身高.GDP.学生成绩等,发现这些被预测的变量都属于连续型变量.然而有些情况下,被预测变量可能是二元变量,即成功或失败.流失或 ...

  6. 扩展progress_timer的计时精度

    progress对外输出精度只有小数点后两位(这点可以运行上节程序进行验证),即精确到0.01秒. 我们使用模板技术仿造一个progress_timer编写一个新类:new_progress_time ...

  7. ACM HDU 2041--超级楼梯题解

    超级楼梯 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  8. Signlar

    后台内部发送到指定客户端 Microsoft.AspNet.SignalR.GlobalHost.ConnectionManager.GetHubContext<tvHub>().Clie ...

  9. 已禁用对分布式事务管理器(MSDTC)的网络访问的解决方法之一

    C# ASP.NET项目提示上述错误,在代码中使用分布式事务提示添加或修改到数据库的时候.添加数据到数据库时,不会设置实体类的主键字段.

  10. OpenCV从入门到放弃系列之——如何扫描图像、利用查找表和计时

    目的 如何遍历图像中的每一个像素? OpenCV的矩阵值是如何存储的? 如何测试我们所实现算法的性能? 查找表是什么?为什么要用它? 测试用例 颜色空间缩减.具体做法就是:将现有颜色空间值除以某个输入 ...