silverlight DependencyObject和DependencyProperty详解
之前我们多次讲到绑定,它会有一个通知作用,那这个通知作用是怎么出来的呢,为什么我们以前的CLR的属性就没有这种通知功能呢?
那是因为现在我们SL中多了这样两个概念--- DependencyObject和DependencyProperty。
DependencyProperty实际上就是在DependencyObject中去使用的。
下面分别来介绍这两个东东。
一、DependencyObject
1、它是SL内置定义好的,并拥有DependencyProperty的类。
2、它是一个准备要去绑定的一个数据对象
3、我们所有的界面元素是由 DependencyObject 派生的。
来一个UML图
一、DependencyProperty
为什么DependencyProperty能提供绑定、继承。。。。这样的功能呢。
下面来说说他的原理:
实际上它是在DependencyObject里面的一个Dictionary, ,这个Dictionary包含了一系列的propertyName , 和 propertyValue 这种名值对,也就是
说我们像刚才的用一个名字去取得它对应的值。用这样的方式,将属性和类之前解耦了。所以我们在对这些属性做一些特征的时候,可以单独得对这些属性操作。
下面用代码来实现DependencyObject和DependencyProperty的原理(注意:只是模仿,SL中的DependencyProperty要更复杂,但原理差不多这样)
自已定义一个DependencyObject
public class MyDependencyObject { #region Dependency Property Principle Code private Dictionary<string, object> properties = new Dictionary<string, object>(); protected object GetValue(MyDependencyProperty property) { if (property.OwnerType == this.GetType()) { return this.properties[property.Name]; } else { // Sample for inherit principle. MyDependencyObject parent = this.GetParentElement(property.OwnerType); return parent.GetValue(property); } } protected void SetValue(MyDependencyProperty property, object value) { this.properties[property.Name] = value; } #endregion #region Private Methods private MyDependencyObject GetParentElement(Type type) { // TODO: Get parent element here. return null; } #endregion }
自己定义一个DependencyProperty
public class MyDependencyProperty { #region Constructor private MyDependencyProperty(string name, Type valueType, Type ownerType, object defaultValue) { this.Name = name; this.ValueType = valueType; this.OwnerType = ownerType; this.DefaultValue = defaultValue; } public static MyDependencyProperty Register(string name, Type valueType, Type ownerType, object defaultValue) { MyDependencyProperty instance = new MyDependencyProperty(name, valueType, ownerType, defaultValue); return instance; } #endregion #region CLR Properties public string Name { get; private set; } public Type ValueType { get; private set; } public Type OwnerType { get; private set; } public object DefaultValue { get; private set; } #endregion }
示例:
public class MyParentElement : MyDependencyObject { public string Text { get { return (string)GetValue(TextProperty); } set { SetValue(TextProperty, value); } } public static readonly MyDependencyProperty TextProperty = MyDependencyProperty.Register("Text", typeof(string), typeof(MyParentElement), "I'm parent."); } public class MyChildElement : MyDependencyObject { public string Text { get { return (string)GetValue(TextProperty); } set { SetValue(TextProperty, value); } } public static readonly MyDependencyProperty TextProperty = MyDependencyProperty.Register("Text", typeof(string), typeof(MyParentElement), "I'm child."); }