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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值