WPF 依赖属性原理

如果你想深入了解 WPF 依赖属性那么你需要了解以下问题

  • 依赖属性和CLR属性的区别?
  • 依赖属性如何支持CLR属性?
  • 元数据如何重写?
  • 属性值继承?
    因为我不精通,所以我不了解,哈哈!不废话了
  1. WPF 依赖属性实现原理

DependencyProperty 类型里存在一个静态属性
private static Hashtable PropertyFromName = new Hashtable();
该属性用以存储我们定义的静态 DependencyProperty 的实例,也就是我们定义的依赖属性,并且 PropertyFromName 是一个哈希表。

哈希表的 Key 为一个 FromNameKey 类型的实例,该类的构造如下

            public FromNameKey(string name, Type ownerType)
            {
                _name = name;
                _ownerType = ownerType;

                _hashCode = _name.GetHashCode() ^ _ownerType.GetHashCode();
            }

可以看到,它是使用依赖属性的 _name 和 _ownerType 作为 key 的。

同时,每次创建的依赖属性都会存放到 RegisteredPropertyList 静态集合中,如下:

        private DependencyProperty(string name, Type propertyType, Type ownerType, PropertyMetadata defaultMetadata, ValidateValueCallback validateValueCallback)
        {
            _name = name;
            _propertyType = propertyType;
            _ownerType = ownerType;
            _defaultMetadata = defaultMetadata;
            _validateValueCallback = validateValueCallback;

            Flags packedData;
            lock (Synchronized)
            {
                packedData = (Flags) GetUniqueGlobalIndex(ownerType, name);

                // 将创建的依赖属性存放到 静态集合
                RegisteredPropertyList.Add(this);
            }

            if (propertyType.IsValueType)
            {
                packedData |= Flags.IsValueType;
            }

            if (propertyType == typeof(object))
            {
                packedData |= Flags.IsObjectType;
            }

            if (typeof(Freezable).IsAssignableFrom(propertyType))
            {
                packedData |= Flags.IsFreezableType;
            }

            if (propertyType == typeof(string))
            {
                packedData |= Flags.IsStringType;
            }

            _packedData = packedData;
        }

那么 DependencyPropertyRegisteredPropertyList 这两个集合有什么用呢?

  • 属性元数据
namespace System.Windows
{
    // 属性元数据类型,公开了三个属性。
    public class PropertyMetadata
    {
        // 强制值回调。
       public CoerceValueCallback CoerceValueCallback { get; set; }

        // 元数据默认值。
       public object DefaultValue { get; set; }

        // 元数据值值改变回调。
       public PropertyChangedCallback PropertyChangedCallback { get; set; }
    }
}

依赖属性类型有以下公开的属性

namespace System.Windows
{
    //
    // 摘要:
    //     Represents a property that can be set through methods such as, styling, data
    //     binding, animation, and inheritance.
    public sealed class DependencyProperty
    {
        //
        // 摘要:
        //     Specifies a static value that is used by the WPF property system rather than
        //     null to indicate that the property exists, but does not have its value set by
        //     the property system.
        public static readonly object UnsetValue;

        //
        // 摘要:
        //     Gets the type that the dependency property uses for its value.
        //
        // 返回结果:
        //     The System.Type of the property value.
        public Type PropertyType { get; }
        //
        // 摘要:
        //     Gets the type of the object that registered the dependency property with the
        //     property system, or added itself as owner of the property.
        //
        // 返回结果:
        //     The type of the object that registered the property or added itself as owner
        //     of the property.
        public Type OwnerType { get; }
        //
        // 摘要:
        //     Gets the name of the dependency property.
        //
        // 返回结果:
        //     The name of the property.
        public string Name { get; }
        //
        // 摘要:
        //     Gets an internally generated value that uniquely identifies the dependency property.
        //
        // 返回结果:
        //     A unique numeric identifier.
        public int GlobalIndex { get; }
        
        // 公开的元数据属性,上述有描述这个类型。
        public PropertyMetadata DefaultMetadata { get; }

        //
        // 摘要:
        //     Gets a value that indicates whether the dependency property identified by this
        //     System.Windows.DependencyProperty instance is a read-only dependency property.
        //
        // 返回结果:
        //     true if the dependency property is read-only; otherwise, false.
        public bool ReadOnly { get; }
        //
        // 摘要:
        //     Gets the value validation callback for the dependency property.
        //
        // 返回结果:
        //     The value validation callback for this dependency property, as provided for the
        //     validateValueCallback parameter in the original dependency property registration.
        public ValidateValueCallback ValidateValueCallback { get; }
    }
}
posted @ 2022-02-11 11:34  RafaelLxf  阅读(262)  评论(0)    收藏  举报