WPF中依赖属性的值是是可以设置为可继承(Inherits)的,这种模式下,父节点的依赖属性会将其值传递给子节点。例如,数据绑定中经常使用的DataContextProperty:

var host = new ContentControl();
    var button = new
Button();
    host.Content = button;

host.DataContext = Guid.NewGuid();
    Contract.Assert(object.Equals(host.DataContext, button.DataContext));

可以看到,虽然没有显示给button的DataContext赋值,但其自然沿袭的父节点的值。

这个特性很大程度上省去了我们的不少代码,那么如何使用自定义的依赖属性也具有这一特性呢,网上找到的例子一般如下:

class
Host : ContentControl
    {
        public
object Value
        {
            get { return (object)GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }

public
static
readonly
DependencyProperty ValueProperty =
            DependencyProperty.Register("Value", typeof(object), typeof(Host), new
FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits));
    }

class
MyButton : Button
    {
        public
object Value
        {
            get { return (object)GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }

public
static
readonly
DependencyProperty ValueProperty = Host.ValueProperty.AddOwner(typeof(MyButton), new
FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits));

}

可以看到,使能依赖属性的基础大体上要如下几步:

  1. 使用FrameworkPropertyMetadataOptions.Inherits使用标记源属性
  2. 使用DependencyProperty.AddOwner注册衍生属性,注册时需要FrameworkPropertyMetadataOptions.Inherits加上标记。

测试用例如下:

var host = new
Host();
    var button = new
MyButton();

host.Content = button;
    host.SetValue(Host.ValueProperty, Guid.NewGuid());
    Contract.Assert(object.Equals(host.GetValue(Host.ValueProperty), button.GetValue(MyButton.ValueProperty)));

这种方式虽然没有什么问题,但Host.ValueProperty.AddOwner(typeof(MyButton)这一截看起来非常别扭,研究了一下,实际上没有这么严格的父子关系,这样写也是可以的:

class
DependcyPropertyHelper
    {
        public
static
DependencyProperty RegistInherits<TOwner>(DependencyProperty property)
        {
            return property.AddOwner(typeof(TOwner), new
FrameworkPropertyMetadata(property.DefaultMetadata.DefaultValue, FrameworkPropertyMetadataOptions.Inherits));
        }
    }

class
DependencyData : DependencyObject
    {
        public
static
readonly
DependencyProperty ValueProperty =
            DependencyProperty.Register("Value", typeof(object), typeof(DependencyData));
    }

class
Host : ContentControl
    {
        public
static
readonly
DependencyProperty ValueProperty = DependcyPropertyHelper.RegistInherits<Host>(DependencyData.ValueProperty);
    }

class
MyButton : Button
    {
        public
static
readonly
DependencyProperty ValueProperty = DependcyPropertyHelper.RegistInherits<MyButton>(DependencyData.ValueProperty);
    }

这样写看起来就舒服一些了。细心的朋友看下就能发现:源属性DependencyData.ValueProperty都没有标记为可继承的(第一种方式下非要标记为可继承的),找了一下,也没有发现官方的详细文档的说明这个规则到底是什么样的,有空发现后再补充。

WPF 中依赖属性的继承(Inherits)的更多相关文章

  1. WPF 使用依赖属性(DependencyProperty) 定义用户控件中的Image Source属性

    原文:WPF 使用依赖属性(DependencyProperty) 定义用户控件中的Image Source属性 如果你要自定义一个图片按钮控件,那么如何在主窗体绑定这个控件上图片的Source呢? ...

  2. WPF的依赖属性和附加属性(用法解释较全)

    转:https://www.cnblogs.com/zhili/p/WPFDependencyProperty.html 一.引言 感觉最近都颓废了,好久没有学习写博文了,出于负罪感,今天强烈逼迫自己 ...

  3. WPF的依赖属性

    Windows Presentation Foundation (WPF) 提供了一组服务,这些服务可用于扩展公共语言运行时 (CLR)属性的功能,这些服务通常统称为 WPF 属性系统.由 WPF 属 ...

  4. wpf 的依赖属性只能在loaded 事件之后才能取到

    wpf 的依赖属性只能在loaded 事件之后才能取到,在构造函数的  InitializeComponent(); 之后取不到 wpf 的依赖属性只能在loaded 事件之后才能取到,在构造函数的  ...

  5. WPF 自定义依赖属性

      原博客地址:http://www.cnblogs.com/DebugLZQ/archive/2012/11/30/2796021.html    DependencyObject和Dependen ...

  6. [转]WPF的依赖属性是怎么节约内存的

    WPF升级了CLR的属性系统,加入了依赖属性和附加属性.依赖属性的使用有很多好处,其中有两点是我认为最为亮眼的: 1)节省内存的开销; 2)属性值可以通过Binding依赖于其它对象上,这就使得我的数 ...

  7. WPF 之 依赖属性与附加属性(五)

    一.CLR 属性 ​ 程序的本质是"数据+算法",或者说用算法来处理数据以期得到输出结果.在程序中,数据表现为各种各样的变量,算法则表现为各种各样的函数(操作符是函数的简记法). ...

  8. WPF利用依赖属性和命令编写自定义控件

    以实例讲解(大部分讲解在代码中) 1,新建一个WPF项目,添加一个用户控件之后在用户控件里面添加几个控件用作测试, <UserControl x:Class="SelfControlD ...

  9. WPF: 只读依赖属性的介绍与实践

    在设计与开发 WPF 自定义控件时,我们常常为会控件添加一些依赖属性以便于绑定或动画等.事实上,除了能够添加正常的依赖属性外,我们还可以为控件添加只读依赖属性(以下统称"只读属性" ...

随机推荐

  1. Vue项目中引入外部文件(css、js、less)

    例子中css文件采用bootstrap.css,js文件采用jQuery,less文件用less.less(自定义文件) 步骤一:安装webpack cnpm install webpack -g 步 ...

  2. ios上传图片显示方向错误问题

    IOS 上传图片方向显示错误问题 问题描述 在使用苹果手机上传图片的时候,发现传完的图片显示出来方向是错误的,竖着的图片会变成横着显示(少部分安卓手机也存在这个问题) 产生原因 ios 相机加入了方向 ...

  3. java JDK动态代理的机制

    一:前言 自己在稳固spring的一些特性的时候在网上看到了遮掩的一句话“利用接口的方式,spring aop将默认通过JDK的动态代理来实现代理类,不适用接口时spring aop将使用通过cgli ...

  4. SpringMVC——如何获取请求参数

    参考 http://www.cnblogs.com/bigdataZJ/p/springmvc2.html (文章讲了几个注解的使用,但不够深入.) 参考 http://www.cnblogs.com ...

  5. javascript中实例方法与类方法的区别

    在javascript中,类有静态属性和实例属性之分,也有静态方法和实例方法之分 类属性(静态属性):通过类直接访问,不需要声明类的实例来访问 类方法(静态方法):通过类直接访问,不需要声明类的实例来 ...

  6. Python学习笔记 - day4 - 流程控制

    Python流程控制 Python中的流程控制主要包含两部分:条件判断和循环. Python的缩进和语法 为什么要在这里说缩进和语法,是因为将要学习的条件判断和分支将会涉及到多行代码,在java.c等 ...

  7. v4l2 Camera详细设置【转】

    转自:http://blog.csdn.net/smilefyx/article/details/39555289 转载自:http://blog.sina.com.cn/s/blog_602f877 ...

  8. Bean利用Resource接口获取资源的几种方式

    Resources的类型 获取resource的方式(xml配置正常进行):

  9. [译]Java8的函数式接口

    Java8引入了 java.util.function 包,他包含了函数式接口,具体的描述在以下api说明文档中: 函数式接口为lambda表达式和方法引用提供目标类型.每个函数式接口有一个单独的抽象 ...

  10. 【hdoj_1009】FatMouse's Trade

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1009< 本题用到贪心策略和结构体排序. 问题简化:现有资本M,N个房间,第i个房间对应着价格为F[i ...