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. springmvc4+hibernate4+activiti5.18(Maven)

    项目下载地址: http://files.cnblogs.com/files/walk-the-Line/springmvc_activiti5.18_hibernate4.zip

  2. jQuery操纵DOM

    一.基本操作 1.html() - 类似于原生DOM的innerHTML属性 *获取 - html(); *设置 - html("html代码"); 2.val() - 类似于原生 ...

  3. python_plot画图参数设置

    # coding:utf-8 import pandas as pd import numpy as np import matplotlib.pyplot as plt # one_hot数据的读取 ...

  4. [转]在树莓派上搭建LAMP服务

    之前介绍过树莓派上LNMP环境的搭建方法,本文将详细介绍如何在树莓派上配置LAMP服务. 为LAMP,是最流行的服务器配置之一,LAMP的含义是: Linux - 操作系统 Apache - 网络服务 ...

  5. 转:在android中button响应的两种方式

    1. 在布局文件中添加button的监听名字 Android:onClick="buttonOnClick" 例如: <Button android:id="@+i ...

  6. rtp/rtsp over http的学习

    要做rtp/rtsp over http, 我对http也有点了解, 以前也做过rtp/rtsp over tcp/udp传输264视频流, 但刚开始还是没有一点思路,想着把http和rtp等联系到一 ...

  7. mapper配置文件中的动态SQL

    <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "- ...

  8. PHPstorm创建注释模版

    /** * $NAME$ * @param * @return * @since $DATE$ * @author Name */$END$ /** * xxxx -­- Controller – 类 ...

  9. Selenium2+python自动化52-unittest执行顺序【转载】

    前言 很多初学者在使用unittest框架时候,不清楚用例的执行顺序到底是怎样的.对测试类里面的类和方法分不清楚,不知道什么时候执行,什么时候不执行. 本篇通过最简单案例详细讲解unittest执行顺 ...

  10. hdu 1062(DFS||dijkstra)

    昂贵的聘礼 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 44870   Accepted: 13259 Descripti ...