参考资料:

  1.http://www.cnblogs.com/Zhouyongh/archive/2009/10/20/1586278.html

  基础知识:

  • DependencyObject & DependencyProperty类位于System.Windows命名空间,程序集:WindowsBase.dll;
  • DependencyObject类通过其各子类开启WPF属性系统服务;
  • 属性系统的主要功能是:将计算属性值和提供值改变的系统通知;
  • DependencyProperty类是另一个在属性系统中起重要作用的类;
  • 依赖属性是一种能够注册到WPF属性系统的属性,可通过Styling、Data Binding和Inheritance进行使用;
  • DependencyProperty类可将依赖属性注册到属性系统中,并提供每个依赖属性的认证和信息;
  • 使用依赖属性的类必须是DependencyObject类的子类,或者说必须是依赖对象才能作为依赖属性的宿主;
  • DependencyProperty不能被直接实例化,因为它没有public的构造函数;
  • DependencyProperty只能使用静态DependencyProperty.Register()方法创建其实例;
  • WPF确保DependencyProperty对象被创建后不能被改变(readonly);
  • WPF允许对象在被创建的时候并不创建包含用于存储数据的空间,可只保留在需要用到数据时能够获得默认值,且借用其他对象的数据或实时分配空间的能力来实现。这种对象即依赖对象,这种实时获取数据的能力则由依赖属性实现。
  • DependencyProperty必须以DependencyObject为宿主,并借助其SetValue和GetValue方法进行数值的写入与读取;
  • 依赖属性必须在静态构造函数中进行设置;
  • DependencyObject有ClearValue的方法,用于删除属性的本地值;
  • 依赖属性的共享,比如,TextBlock.FontFamily属性和Control.FontFamily属性指向同一个静态的依赖项属性TextElement.FontFamily;使用DependencyProperty.AddOwner()方法重用该属性;
  • 附加属性也是依赖属性的一种,定义附加属性需要使用RegisterAttached()方法;
  • ValidateValueCallback回调函数可接受或拒绝新值,用于捕获明显的违反属性约束的错误;而CoerceValueCallback回调函数可将新值改为更能被接受的值,有点类似Validate的效果;

   顺序:CoerceValueCallbackValidateValueCallback如果前两个阶段都成功,触发PropertyChangedCallback方法。▲

  常用类及其一些方法:

 DependencyObject类中的SetValue()和GetValue()方法:

//
// 摘要:
// 返回 System.Windows.DependencyObject 的此实例上的依赖项属性的当前有效值。
//
// 参数:
// dp:
// 要为其检索值的属性的 System.Windows.DependencyProperty 标识符。
//
// 返回结果:
// 返回当前的有效值。
//
// 异常:
// System.InvalidOperationException:
// 指定的 dp 或其值无效,或者指定的 dp 不存在。
public object GetValue(DependencyProperty dp);      //
// 摘要:
// 设置依赖项属性的本地值,该依赖项属性由其标识符指定。
//
// 参数:
// dp:
// 要设置的依赖项属性的标识符。
//
// value:
// 新的本地值。
//
// 异常:
// System.InvalidOperationException:
// 尝试修改只读依赖项属性,或尝试修改密封 System.Windows.DependencyObject 上的属性。
//
// System.ArgumentException:
// value 的类型不是为 dp 属性注册时使用的正确类型。
public void SetValue(DependencyProperty dp, object value);
//
// 摘要:
// 设置只读依赖项属性的本地值,该依赖项属性由其 System.Windows.DependencyPropertyKey 标识符指定。
//
// 参数:
// key:
// 要设置的属性的 System.Windows.DependencyPropertyKey 标识符。
//
// value:
// 新的本地值。
public void SetValue(DependencyPropertyKey key, object value);

       DependencyProperty类的Register方法原型:

 //
// 摘要:
// 使用指定的属性名称、属性类型和所有者类型注册依赖项属性。
//
// 参数:
// name:
// 要注册的依赖项对象的名称。 在所有者类型的注册命名空间内,名称必须是唯一的。
//
// propertyType:
// 属性的类型。
//
// ownerType:
// 正注册依赖项对象的所有者类型。
//
// 返回结果:
// 一个依赖项对象标识符,应使用它在您的类中设置 public static readonly 字段的值。 然后,在以后使用该标识符引用依赖项对象,用于某些操作,例如以编程方式设置其值,或者获取元数据。
public static DependencyProperty Register(string name, Type propertyType, Type ownerType);
//
// 摘要:
// 使用指定的属性名称、属性类型、所有者类型和属性元数据注册依赖项属性。
//
// 参数:
// name:
// 要注册的依赖项对象的名称。
//
// propertyType:
// 属性的类型。
//
// ownerType:
// 正注册依赖项对象的所有者类型。
//
// typeMetadata:
// 依赖项对象的属性元数据。
//
// 返回结果:
// 一个依赖项对象标识符,应使用它在您的类中设置 public static readonly 字段的值。 然后,在以后使用该标识符引用依赖项对象,用于某些操作,例如以编程方式设置其值,或者获取元数据。
public static DependencyProperty Register(string name, Type propertyType, Type ownerType, PropertyMetadata typeMetadata);
//
// 摘要:
// 使用指定的属性名称、属性类型、所有者类型、属性元数据和属性的值验证回调来注册依赖项属性。
//
// 参数:
// name:
// 要注册的依赖项对象的名称。
//
// propertyType:
// 属性的类型。
//
// ownerType:
// 正注册依赖项对象的所有者类型。
//
// typeMetadata:
// 依赖项对象的属性元数据。
//
// validateValueCallback:
// 对回调的引用,除了典型的类型验证之外,该引用还应执行依赖项对象值的任何自定义验证。
//
// 返回结果:
// 一个依赖项对象标识符,应使用它在您的类中设置 public static readonly 字段的值。 然后,在以后使用该标识符引用依赖项对象,用于某些操作,例如以编程方式设置其值,或者获取元数据。
public static DependencyProperty Register(string name, Type propertyType, Type ownerType, PropertyMetadata typeMetadata, ValidateValueCallback validateValueCallback);

◎ ValidateValueCallback的定义:

namespace System.Windows
{
// 摘要:
// 表示用作回调的方法,用于验证依赖项属性的值是否有效。
//
// 参数:
// value:
// 要验证的值。
//
// 返回结果:
// 如果该值通过了验证,则为 true;如果提交的值无效,则为 false。
public delegate bool ValidateValueCallback(object value);
}

◎ PropertyMetaData类:

// 摘要:
// 定义依赖项对象在应用于特定类型(包括该属性向其注册的条件)时行为的某些方面。
public PropertyMetadata();
//
// 摘要:
// 使用此元数据将应用于的依赖项对象的指定默认值,初始化 System.Windows.PropertyMetadata 类的新实例。
//
// 参数:
// defaultValue:
// 要为依赖项对象指定的默认值,通常作为某种特定类型的值提供。
//
// 异常:
// System.ArgumentException:
// defaultValue 不能设置为值 System.Windows.DependencyProperty.UnsetValue;请参见“备注”。
public PropertyMetadata(object defaultValue);
//
// 摘要:
// 用指定的 System.Windows.PropertyChangedCallback 实现引用初始化 System.Windows.PropertyMetadata
// 类的新实例。
//
// 参数:
// propertyChangedCallback:
// 对处理程序实现的引用,每当属性的有效值更改时,属性系统都将调用该处理程序实现。
public PropertyMetadata(PropertyChangedCallback propertyChangedCallback);
//
// 摘要:
// 用指定的默认值和 System.Windows.PropertyChangedCallback 实现引用初始化 System.Windows.PropertyMetadata
// 类的新实例。
//
// 参数:
// defaultValue:
// 依赖项对象的默认值,通常作为某种特定类型的值提供。
//
// propertyChangedCallback:
// 对处理程序实现的引用,每当属性的有效值更改时,属性系统都将调用该处理程序实现。
//
// 异常:
// System.ArgumentException:
// defaultValue 不能设置为值 System.Windows.DependencyProperty.UnsetValue;请参见“备注”。
public PropertyMetadata(object defaultValue, PropertyChangedCallback propertyChangedCallback);
//
// 摘要:
// 用指定的默认值和回调初始化 System.Windows.PropertyMetadata 类的新实例。
//
// 参数:
// defaultValue:
// 依赖项对象的默认值,通常作为某种特定类型的值提供。
//
// propertyChangedCallback:
// 对处理程序实现的引用,每当属性的有效值更改时,属性系统都将调用该处理程序实现。
//
// coerceValueCallback:
// 对处理程序实现的引用,每当属性系统对该属性调用 System.Windows.DependencyObject.CoerceValue(System.Windows.DependencyProperty)
// 时都将调用此处理程序实现。
//
// 异常:
// System.ArgumentException:
// defaultValue 不能设置为值 System.Windows.DependencyProperty.UnsetValue;请参见“备注”。
public PropertyMetadata(object defaultValue, PropertyChangedCallback propertyChangedCallback, CoerceValueCallback coerceValueCallback);

◎ CoerceValueCallback的定义:

    / / 摘要:
// 为只要重新计算依赖项属性值或专门请求强制转换时就调用的方法提供一个模板。
//
// 参数:
// d:
// 该属性所在的对象。 在调用该回调时,属性系统将会传递该值。
//
// baseValue:
// 该属性在尝试执行任何强制转换之前的新值。
//
// 返回结果:
// 强制转换后的值(采用适当的类型)。
public delegate object CoerceValueCallback(DependencyObject d, object baseValue);



    ★对DependencyObject和DependencyProperty的模拟,见源博客链接http://www.cnblogs.com/eagle1986/archive/2012/08/17/2643332.html:★

public class MyDenpendencyObject
{
private Dictionary<string, object> properties = new Dictionary<string, object>(); protected object GetValue(MyDenpendencyProperty property)
{
if (property.OwnerType == this.GetType())
{
return this.properties[property.Name];
}
else
{
MyDenpendencyObject parent = this.GetParentElement(property.OwnerType);
return parent.GetValue(property);
}
} protected void SetValue(MyDenpendencyProperty property, object value)
{
this.properties[property.Name] = value;
} private MyDenpendencyObject GetParentElement(Type type)
{
return null;
}
} public class MyDenpendencyProperty
{
private MyDenpendencyProperty(string name, Type valueType, Type ownerType, object defaultValue)
{
this.Name = Name;
this.ValueType = valueType;
this.OwnerType = ownerType;
this.DefaultValue = defaultValue;
} public static MyDenpendencyProperty Register(string name, Type valueType, Type ownerType, object defaultValue)
{
return new MyDenpendencyProperty(name, valueType, ownerType, defaultValue);
} public string Name
{
get;
private set;
} public Type ValueType
{
get;
private set;
} public Type OwnerType
{
get;
private set;
} public object DefaultValue
{
get;
private set;
}
} public class MyParentElement : MyDenpendencyObject
{
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
} public static readonly MyDenpendencyProperty TextProperty =
MyDenpendencyProperty.Register("Text", typeof(string), typeof(MyParentElement), "This is a super class.");
} public class MyChildElement : MyDenpendencyObject
{
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
} public static readonly MyDenpendencyProperty TextProperty =
MyDenpendencyProperty.Register("Text", typeof(string), typeof(MyParentElement), "This is a sub-class.");
}

WPF基础学习笔记整理 (五) DependencyObject & DependencyProperty的更多相关文章

  1. WPF基础学习笔记整理 (一)

    基础知识: WPF:Windows Presentation Foundation,用于Windows的现代图形显示系统: WPF用于编写应用程序的表示层: 引入“内置硬件加速”和“分辨率无关”: S ...

  2. WPF基础学习笔记整理 (九) 资源

    基础知识: WPF的资源是一种保管一系列有用对象的简单方法,方便于重用. WPF UI元素的Resources属性,都是继承自FrameworkElement列,且其类型为ResourceDictio ...

  3. WPF基础学习笔记整理 (八) 命令

    基础知识: 命令是应用程序的任务,并跟踪任务是否能够被执行. 命令不包含执行应用程序任务的代码. 命令是比事件更高级的元素.默认的命令目标是当前获得焦点的元素. 良好的Win应用程序,应用程序逻辑不应 ...

  4. WPF基础学习笔记整理 (七) Binding绑定

    基础知识: 数据绑定是一种关系,该关系告诉WPF从源对象提取一些信息,并用这些信息设置目标对象的属性:目标对象始终是依赖属性,而源对象则可以是任何内容. BindingOperations类,提供静态 ...

  5. WPF基础学习笔记整理 (六) RoutedEvent路由事件

    基础知识: 传统的事件模型中,会在消息触发时将消息通过事件传给事件的订阅者(显式的事件订阅),事件订阅者使用事件处理程序来做出响应.事件订阅者必须能够直接访问到事件的宿主(拥有者). 路由事件的事件的 ...

  6. WPF基础学习笔记整理 (二) XAML

    基础知识: XAML:Extensible Application Markup Language, zammel: 用于实例化.NET对象的标记语言: XMAL使用树形逻辑结构描述UI: BAML: ...

  7. WPF基础学习笔记整理 (四) 布局

    WPF使用的是容器(container)进行布局: WPF窗口(Window类型)只能包含单个元素,故为了放置多个元素并增强界面效果,引入了容器: WPF布局容器都派生自System.Windows. ...

  8. WPF基础学习笔记整理 (三) x命名空间

    “x命名空间”中x是XAML的首字母,用来引导XAML编译器把XAML代码编译成CLR代码.下边的图片表格列举了该命名空间部分成员及其作用,更多请见URL:https://msdn.microsoft ...

  9. Python基础学习笔记(五)常用字符串内建函数

    参考资料: 1. <Python基础教程> 2. http://www.runoob.com/python/python-strings.html 3. http://www.liaoxu ...

随机推荐

  1. Spark Storage(一) 集群下的区块管理

    Storage模块 在Spark中提及最多的是RDD,而RDD所交互的数据是通过Storage来实现和管理 Storage模块整体架构 1. 存储层 在Spark里,单节点的Storage的管理是通过 ...

  2. 优化Ubuntu 16.04系统的几件事

    安装完Ubuntu 16.04后,要更换为国内的软件源: sudo gedit /etc/apt/sources.list #用文本编辑器打开源列表 在文件开头添加下面的阿里云的软件源: deb ht ...

  3. [LeetCode] 286. Walls and Gates_Medium tag: BFS

    You are given a m x n 2D grid initialized with these three possible values. -1 - A wall or an obstac ...

  4. PNG格式图片常见转换方法

    前言 最近碰到一个需要将图片由原始的PNG转化为JPG的需求,由于PNG图片本身质量等原因,导致转化为JPG之后,存在失真的问题,后来一个同事分享了下述的HighQualityPNGToJPG方法解决 ...

  5. AdaBoost Classifier和Regressor

    Adaboost原理传送门 AdaBoost在我看理论课程的时候,以分类为例子来讲解的,谁知道sklearn里面基本上都有classifier和regressor两种.这个倒是我没想到的!!! fro ...

  6. 【kafka学习之四】kafka集群性能测试

    kafka集群的性能受限于JVM参数.服务器的硬件配置以及kafka的配置,因此需要对所要部署kafka的机器进行性能测试,根据测试结果,找出符合业务需求的最佳配置. 1.kafka broker j ...

  7. 每天一个Linux命令(1)ls命令

    ls是list的缩写,ls命令是Linux系统下最常用的命令之一. ls命令用于打印当前目录的清单,如果指定其它目录,那么就会显示其他目录的文件及文件夹的清单. 通过ls 命令还可以查看文件其它的详细 ...

  8. Qt学习之路(45): 自定义model之一

    前面我们说了Qt提供的几个预定义model.但是,面对变化万千的需求,那几个model是远远不能满足我们的需要的.另外,对于Qt这种框架来说,model的选择首先要能满足绝大多数功能的需要,这就是说, ...

  9. Python之路----迭代器与生成器

    一.迭代器 L=[1,,2,3,4,5,] 取值:索引.循环for 循环for的取值:list列表 dic字典 str字符串 tuple元组 set f=open()句柄 range() enumer ...

  10. 文件和打印机共享 win7 and xp

    Win7 摘自:https://www.xp510.com/article/4249.html 首先开启服务 方法:开始---所有程序---附件---运行---输入services.msc----确定 ...