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. iOS 快速框架搭建项目

    项目目录 Pod第三方 gitHub地址 https://github.com/henusjj/Basic-project-framework

  2. java基础学习(一)hashcode

    hashcode的作用 hashCode()方法是从Object类继承过来的,Object类中的hashCode()方法返回的是对象在内存中地址转换成的int值,如果对象没有重写hashCode()方 ...

  3. HDU2594(简单KMP)

    Simpsons’ Hidden Talents Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java ...

  4. Ubuntu Touch环境搭建

    最近搞了一下Nexus 5的MultiRom Manger,体验了一把Ubuntu Touch和Android L,总体感觉还不错,不过Android L的NFC驱动还有问题,Ubuntu Touch ...

  5. 哪些情况会导致OOM

    1. 堆溢出 java堆用于存储对象实例,只要不断地创建对象,并且这些对象不会被回收(什么情况对象不会被回收呢?如:由于GC Root到对象之间有可达路径,所以垃圾回收机制不会清除这些对象),那么,当 ...

  6. 程序员面试宝典 笔记(第六章 预处理 const 和sizeof())

    void main() { "; cout<< cout<< "; cout<< cout<<strlen(ss2)<< ...

  7. 【bzoj4282】慎二的随机数列

    扯几句题外的,最近在看Fate/StayNight,对此人毫无好感…… 每次减一下当前可辨认数,然后随意dp一个LIS,最后记得加回去就好. #include<bits/stdc++.h> ...

  8. AC日记——[JSOI2007]建筑抢修 bzoj 1029

    1029 思路: 贪心,而且,stl水过: 然而神特么输出que.size()就错! 代码: #include <queue> #include <cstdio> #inclu ...

  9. C# 通过串口发送短信

    手机短信群发作为企业日常通知,公告,天气预报等信息的一个发布平台,在于成本低,操作方便等诸多特点,成为企业通讯之首选.本文介绍短信的编码方式,AT指令以及用C#实现串口通讯的方法. 前言目前,发送短信 ...

  10. (十三)MySQL主从复制

    (1)工作原理 (2)主从实现 1) 环境介绍 cat /etc/redhat-release CentOS Linux release 7.3.1611 (Core) MySQL版本:5.7 mys ...