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

  • 相关阅读:
    PHP
    Python语言特性
    Selenium2+python自动化
    Linux命令--系统管理
    Linux命令--网络管理
    Linux命令--压缩解压(简化版)
    Linux--压缩解压命令
    Linux命令--用户管理
    Linux命令--获取帮助
    Linux命令--权限管理
  • 原文地址:https://www.cnblogs.com/TianFang/p/3784927.html
Copyright © 2011-2022 走看看