1.新建Student类,继承于DependencyObject
创建依赖属性的快捷输入propdp
注册依赖属性时候可以将元数据默认值为null,这样表示该属性用到时候才赋值,不用时候为空,不占用内存控件,不像普通的CLR属性,会默认占用内存空间
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace WpfApp1
{
public class Student:DependencyObject
{
public string Name
{
get { return (string)GetValue(NameProperty); }
set { SetValue(NameProperty, value); }
}
// Using a DependencyProperty as the backing store for Name. This enables animation, styling, binding, etc...
public static readonly DependencyProperty NameProperty =
DependencyProperty.Register("Name", typeof(string), typeof(Student), new PropertyMetadata(null));
}
}
2.查看Register源码
public static DependencyProperty Register(string name, Type propertyType, Type ownerType, PropertyMetadata typeMetadata)
{
return Register(name, propertyType, ownerType, typeMetadata, null);
}
3,再进一层
public static DependencyProperty Register(string name, Type propertyType, Type ownerType, PropertyMetadata typeMetadata, ValidateValueCallback validateValueCallback)
{
RegisterParameterValidation(name, propertyType, ownerType);
PropertyMetadata defaultMetadata = null;
if (typeMetadata != null && typeMetadata.DefaultValueWasSet())
{
defaultMetadata = new PropertyMetadata(typeMetadata.DefaultValue);
}
DependencyProperty dependencyProperty = RegisterCommon(name, propertyType, ownerType, defaultMetadata, validateValueCallback);
if (typeMetadata != null)
{
dependencyProperty.OverrideMetadata(ownerType, typeMetadata);
}
return dependencyProperty;
}
4.RegisterCommon
从FromNameKey类的构造方法,可以看出通过包装属性名和OwnerType拿到哈希值
FromNameKey key = new FromNameKey(name, ownerType);
public FromNameKey(string name, Type ownerType)
{
_name = name;
_ownerType = ownerType;
_hashCode = (_name.GetHashCode() ^ _ownerType.GetHashCode());
}
PropertyFromName[key] = dependencyProperty;
private static Hashtable PropertyFromName = new Hashtable();这里可以看到PropertyFromName是一个hashtable,然后把具有唯一哈希值的FromNameKey对象存到hashtable中,也就是说依赖属性,只是个索引,真正是存在依赖属性的Hashtable(PropertyFromName)中
private static DependencyProperty RegisterCommon(string name, Type propertyType, Type ownerType, PropertyMetadata defaultMetadata, ValidateValueCallback validateValueCallback)
{
FromNameKey key = new FromNameKey(name, ownerType);
lock (Synchronized)
{
if (PropertyFromName.Contains(key))
{
throw new ArgumentException(MS.Internal.WindowsBase.SR.Get("PropertyAlreadyRegistered", name, ownerType.Name));
}
}
if (defaultMetadata == null)
{
defaultMetadata = AutoGeneratePropertyMetadata(propertyType, validateValueCallback, name, ownerType);
}
else
{
if (!defaultMetadata.DefaultValueWasSet())
{
defaultMetadata.DefaultValue = AutoGenerateDefaultValue(propertyType);
}
ValidateMetadataDefaultValue(defaultMetadata, propertyType, name, validateValueCallback);
}
DependencyProperty dependencyProperty = new DependencyProperty(name, propertyType, ownerType, defaultMetadata, validateValueCallback);
defaultMetadata.Seal(dependencyProperty, null);
if (defaultMetadata.IsInherited)
{
dependencyProperty._packedData |= Flags.IsPotentiallyInherited;
}
if (defaultMetadata.UsingDefaultValueFactory)
{
dependencyProperty._packedData |= Flags.IsPotentiallyUsingDefaultValueFactory;
}
lock (Synchronized)
{
PropertyFromName[key] = dependencyProperty;
}
if (TraceDependencyProperty.IsEnabled)
{
TraceDependencyProperty.TraceActivityItem(TraceDependencyProperty.Register, dependencyProperty, dependencyProperty.OwnerType);
}
return dependencyProperty;
}