WPF学习(三) - 依赖属性
学习WPF时,我在看一本叫做“深入浅出WPF”的书。整整20页都在讲依赖性性和附加属性,反复看了几遍居然还是不懂,真是郁闷。
上一篇中WPF绑定的例子,其实已经用到了依赖属性。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// 作为被绑定的目标类,必须从DependencyObject派生 // 这样定义的类才能满足SetBinding方法的第一个参数的类型要求 // 还要额外定义一个依赖属性,用来满足SetBinding方法的第二个参数要求 // 用DependencyObject派生方法GetValue和SetValue,控制属性的存、取 public class UIClass : System.Windows.DependencyObject { public string MyText { get { return ( string ) GetValue ( MyTextProperty ); } set { SetValue ( MyTextProperty, value ); } } public static readonly System.Windows.DependencyProperty MyTextProperty = System.Windows.DependencyProperty.Register ( "MyText", typeof ( string ), typeof ( UIClass ) ); }
通过这个例子,我的认识是:想把展示层的属性值同步给数据层,必须用依赖属性。SetBinding方法第二个参数要求必须是依赖属性类型。
在上一篇中,用Winform实现数据同步的方法,建立同步关系过程存在不足。而WPF使用依赖属性,解决了这个难题。
那么,依赖属性是如何神奇地做到这一点的呢?之前,我说过,Winform实现很困难,但不等于实现不了,这个命题是这样的:
已知:某个实例和它的属性名称字符串,如何获取这个实例的这个属性值?注意,这个要求不是在编码阶段,而是在运行阶段实现的功能。
它应该是这样一个方法:GetObjectPropertyValue(object o, string propertyName) //根据传入的对象及其某个属性的名称,返回属性值
不许用反射!!!这么个简单的要求,我找不到一个基本的方法来实现……这不能不让我想起最初接触编程时,总是用替代的办法,实现一些标准的功能。解决的思路是:反正要求就是按名称取一个值,我建立一个名称+值的对照表,这样就实现了按名称存/取属性值了。好吧,还有实例也要刷下存在感,对照表里加一项,描述实例。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class PropertyContainer { static List<InstanceNameValue> lstINV = new List<InstanceNameValue> ( ); public void Register ( int instance, string propertyName) { lstINV.Add ( new InstanceNameValue ( ) { InstanceHashCode = instance, PropertyName = propertyName } ); } public object GetValue ( object o, string propertyName ) { foreach ( InstanceNameValue item in lstINV ) { if ( o.GetHashCode ( ) == item.InstanceHashCode && propertyName == item.PropertyName ) { return item.Value; } } return null; } } //实例、属性名、值 class InstanceNameValue { public int InstanceHashCode; public string PropertyName; public object Value; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class CheatClass { public string CheatProperty { get { return (string)PropertyContainer.GetValue ( this, "WhatEverName" ); } } }
调用PropertyContainer.GetValue方法,传入实例和属性名,读、写这个实例对应的属性值,似乎可以用了呢。其实,这就是在骗人,我从来就没有真正的读/写过这个实例的属性值(如果他真的是那种传统意义上的类和属性实例化出来的),我一直在用一个替身保存我想保存在属性字段中的值。甚至于,这个实例所在的类根本就没有这个字段。
明白这些的时候,十分怒火。用了这么多年的面向对象,如今,类的属性不再需要定义字段去存储,它们在运行时被归拢到一堆,放在一口锅里。对象已不再是那个对象,它可以只保留那12个字节,刷个存在感。类与类之间还有关系吗?对象与对象之间还有关系有吗??!!!还设计什么架构,还搞什么数据结构。随便定义个空类,运行去吧,想添啥属性随意添。
曾经有个小朋友,这样设计数据表结构:表名、字段名、记录编号、字段值,还很沾沾自喜的向我炫耀自己设计了一个通用的表结构。我一巴掌抽过去,科班出身的人把数据结构学到狗身上去了!如今,微软一巴掌抽回来,这么任性的结构,.net也要用,咋地吧!!!
怒了,今天就到这……