WPF 依赖属性原理
如果你想深入了解 WPF 依赖属性那么你需要了解以下问题
- 依赖属性和CLR属性的区别?
- 依赖属性如何支持CLR属性?
- 元数据如何重写?
- 属性值继承?
因为我不精通,所以我不了解,哈哈!不废话了
- 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;
}
那么 DependencyProperty 和 RegisteredPropertyList 这两个集合有什么用呢?
- 属性元数据
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; }
}
}
浙公网安备 33010602011771号