WPF 中依赖属性的继承(Inherits)

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

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没有标记为可继承的(第一种方式下非要标记为可继承的),找了一下,也没有发现官方的详细文档的说明这个规则到底是什么样的,有空发现后再补充。

目录
相关文章
|
6月前
|
C#
2000条你应知的WPF小姿势 基础篇<57-62 依赖属性进阶>
2000条你应知的WPF小姿势 基础篇<57-62 依赖属性进阶>
20 0
|
6月前
|
存储 开发框架 .NET
2000条你应知的WPF小姿势 基础篇<51-56 依赖属性>
2000条你应知的WPF小姿势 基础篇<51-56 依赖属性>
22 0
|
9月前
|
C#
WPF属性---重复样式和触发器
WPF属性---重复样式和触发器
70 0
|
前端开发 C# 图形学
【WPF】WPF开发用户控件、用户控件属性依赖DependencyProperty实现双向绑定、以及自定义实现Command双向绑定功能演示
Wpf开发过程中,最经常使用的功能之一,就是用户控件(UserControl)了。用户控件可以用于开发用户自己的控件进行使用,甚至可以用于打造一套属于自己的UI框架。依赖属性(DependencyProperty)是为用户控件提供可支持双向绑定的必备技巧之一,同样用处也非常广泛。
782 0
【WPF】WPF开发用户控件、用户控件属性依赖DependencyProperty实现双向绑定、以及自定义实现Command双向绑定功能演示
WPF项目中不支持 ResizingPanel,未在类型“ResizingPanel”中找到可附加的属性“ResizeWidth”
WPF项目中不支持 ResizingPanel,未在类型“ResizingPanel”中找到可附加的属性“ResizeWidth”
|
C#
WPF整理-为控件添加自定义附加属性
原文:WPF整理-为控件添加自定义附加属性 附加属性,大家都不陌生,最常见的是Canvas.Left/Canvas.Top,类似的也有Grid.Row/Grid.Column等附加属性。举个最常见的例子 需要说明的是并不是所有的附加属性都是元素放进去后才会有附加效果,上面的例子只是刚好是这种错觉的巧合情况,Grid.Row也属于这种巧合。
2042 0
|
C#
WPF XAML 资源样式模板属性存放位置
原文:WPF XAML 资源样式模板属性存放位置 WPF的XAML 资源申明 类似HTML。 整体来说分3种1.行类资源样式属性 1.1 行内属性 1.2 行内样式 模板(没多大意义) ...
1108 0
|
C#
WPF 属性变更通知类的实现
原文:WPF 属性变更通知类的实现 平时用依赖属性多一些,普通属性的变更通知知道有这个方法,但是老是忘记名字,再写一遍吧。
981 0
|
C#
WPF的IsSynchronizedWithCurrentItem属性
原文:WPF的IsSynchronizedWithCurrentItem属性 如果两个控件都绑定到同一个源(ObservableCollection)集合视图时,该对象会自动绑定到该视图的 CurrentItem。
953 0
|
C# 数据安全/隐私保护
WPF 使用附加属性增加控件属性
原文:WPF 使用附加属性增加控件属性 使用附加属性增加控件属性,使得这个附加属性在使用的时候没有局限性,可以在任何的控件中使用它来增加所需要的属性,使得控件的属性使用起来非常灵活   一、自定义附加属性 1 2 3 4 5 6 7 8 9 10 11 ...
853 0