1 WPF中的依赖属性之一

前端之家收集整理的这篇文章主要介绍了1 WPF中的依赖属性之一前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

依赖属性是wpf中一个新的概念,这种属性是当前的类没有自己的属性,但是可以通过Binding获取其他的对象的属性。当然在使用的过程中,依赖属性一般要被包装成CLR属性

依赖属性在实际编码中是怎样应用的,不是这篇文章的讨论的内容,此篇主要讨论一下依赖属性是怎样实现的。

首先我们看示例代码:此代码是从http://www.silverlightchina.net/html/study/WPF/2011/0405/6659_3.html中截取出来的。大家可以看此文章,感觉讲的还算通俗易懂。

   
    class MyDependencyProperty
    {
        internal static Dictionary<object,MyDependencyProperty>RegisteredDps = new Dictionary<object,MyDependencyProperty>();
        internal string Name;
        internal object Value;
        /**当当前的依赖属性没有被赋值过,那么,GetValue就会缺省从HashCode为索引的哈希表中获取缺省值。
         */
        internal object HashCode;
        private static int globalIndex = 0;//所有的属性值的index将都会大于0
        /**index是当前注册DependencyProperty中的序号- 实际上是检索当前依赖属性的检索号
         */
        internal int Index;

        private MyDependencyProperty(string name,Type propertyName,Type ownerType,object defaultValue)
        {
            this.Name = name;
            this.Value = defaultValue;
            this.HashCode = name.GetHashCode() ^ ownerType.GetHashCode();
        }

        public static MyDependencyProperty Register(string name,Type propertyType,object defaultValue)
        {
            MyDependencyProperty dp = new MyDependencyProperty(name,propertyType,ownerType,defaultValue);
            globalIndex++;
            dp.Index = globalIndex;
            RegisteredDps.Add(dp.HashCode,dp);
            return dp;
        }
    }

    internal struct EffectiveValueEntry
    {
        internal int PropertyIndex { get; set; }
        internal object Value { get; set; }
    }

    class MyDependencyObject
    {
        //这个list用来存储设置的依赖属性值,包括这个类的所有的依赖属性,都会在设置后存储在这里
        private List<EffectiveValueEntry> _effectiveValues = new List<EffectiveValueEntry>();

        public object GetValue(MyDependencyProperty dp)
        {
            //在数据结构中查找对应的依赖属性是否在本地有值。
            EffectiveValueEntry effectiveValue = _effectiveValues.FirstOrDefault((i) => i.PropertyIndex == dp.Index);
            if (effectiveValue.PropertyIndex != 0)
            {//如果获取的元素的PropertyIndex不等于0,说明本地存在这个属性的值
                return effectiveValue.Value;
            }
            else
            {//本地不存在就去Dictionary中区查找。
                return MyDependencyProperty.RegisteredDps[dp.HashCode].Value;
            }
        }
        public void SetValue(MyDependencyProperty dp,object value)
        {
            //在数据结构中查找对应的依赖属性是否在本地有值。
            EffectiveValueEntry effectiveValue = _effectiveValues.FirstOrDefault((i) => i.PropertyIndex == dp.Index);
            if (effectiveValue.PropertyIndex != 0)
            {//如果获取的元素的PropertyIndex不等于0,说明本地存在这个属性的值
                effectiveValue.Value = value;
            }
            else
            {//本地不存在,但是我们进行了Setvalue的调用,所以需要在本地创建一个该属性的数据结构
                effectiveValue = new EffectiveValueEntry() { PropertyIndex = dp.Index,Value = value };
                _effectiveValues.Add(effectiveValue);
            }
        }
    }
代码中有一些注释。此外,在附上一张自己对依赖属性理解的图。从图中可以看出,所有的依赖属性注册到了DependencyProperty的静态变量Dictionary<object,DependecyProperty>中,其中object来存储注册DependecyProperty的哈希值。在依赖属性中,index是一个很重主要的值,此值是当前依赖属性注册到Dictionary中的序号。而含有依赖属性的对象都是继承依赖对象(DependencyObject)的,在依赖对象(DependencyObject)中,含有一个此类中所有依赖属性的列表,此列表包含着依赖属性的值。而依赖对象(DepedencyObject)的列表和依赖属性(DependencyProperty)唯一的联系点就是Index值。

猜你在找的设计模式相关文章