吴佳鑫的个人专栏

当日事当日毕,没有任何借口

导航

silverlight DependencyObject和DependencyProperty详解

之前我们多次讲到绑定,它会有一个通知作用,那这个通知作用是怎么出来的呢,为什么我们以前的CLR的属性就没有这种通知功能呢?

那是因为现在我们SL中多了这样两个概念--- DependencyObject和DependencyProperty。

DependencyProperty实际上就是在DependencyObject中去使用的。

 

下面分别来介绍这两个东东。

一、DependencyObject

1、它是SL内置定义好的,并拥有DependencyProperty的类。

2、它是一个准备要去绑定的一个数据对象  

3、我们所有的界面元素是由 DependencyObject 派生的。

 来一个UML图

 

一、DependencyProperty

•Parameters for Registration
–Name of Property
–Type of Property
–Type of Owner
–PropertyMetadata
•Types of Registration
–Simple Property ‘DependencyProperty.Register’     --注册依赖属性
–Attach Property ‘DependencyProperty.RegisterAttached’   --注册附加属性
–Sample: Canvas.Top, Grid.Column
•Principle of Dependency Property
–DependencyObject.Dictionary<propertyName,  propertyValue>
•Why Use Dependency Property
–Binding, Inherit, Multiple Value Providers, Attachment

 

 

 

为什么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.");
    }

 

posted on 2012-08-17 00:34  _eagle  阅读(2452)  评论(2编辑  收藏  举报