【问题标题】:Dependency property value is not inherited依赖属性值不被继承
【发布时间】:2014-03-19 19:14:59
【问题描述】:

我用FrameworkPropertyMetadataOptions.Inherits声明了一个依赖属性:

public static class DesignerItemStyles {
    public static readonly DependencyProperty HeaderBackgroundProperty = 
        DependencyProperty.RegisterAttached(
            "HeaderBackground", typeof(Brush), typeof(DesignerItemStyles),
            new FrameworkPropertyMetadata(
                Brushes.DesignerViewElementHeaderBackground,
                FrameworkPropertyMetadataOptions.Inherits));

    /* Below are Get & Set as usual */
}

它有点工作,但不知何故不适用于整个视觉树。这是一个屏幕截图,显示了从 HeaderedDesignerItemChrome 继承值的 ContentPresenter

现在,屏幕截图显示了ContentPresenter 的内容,它不继承该值。它也没有设置为其他值 - 它是默认值:

知道为什么吗?

【问题讨论】:

  • 如果 ContentPresenter 有一个 DP 调用 HeaderBackground 这将起作用,否则它是一个附加属性。
  • 它是一个附加属性。我在顶部发布了声明。
  • 可能是您在 DesignerItemsPresenter 中做某事,也许是这个属性的一些元数据覆盖?
  • 不,没有那种事
  • 如果我错了,请纠正我,Brushes.DesignerViewElementHeaderBackground == #FFE9ECEE 这是默认值。这就是我们在 snoop 中看到的内容,然后在您设置#FFADE180 的某个地方可以显示它的设置位置吗?

标签: wpf dependency-properties


【解决方案1】:

使用它并不是那么直接,因为需要遵循一些规则来实现具有可继承值的属性。他们在这里:

在父节点上,依赖属性必须定义为附加属性。您仍然可以声明属性 getter/setter,但必须附加属性。这是简单的声明:

public static readonly DependencyProperty InheritedValueProperty =
   DependencyProperty.RegisterAttached("InheritedValue",
   typeof(int), typeof(MyClass), new FrameworkPropertyMetadata(0, 
   FrameworkPropertyMetadataOptions.Inherits));
public static int GetInheritedValue(DependencyObject target)
{
   return (int)target.GetValue(InheritedValueProperty);
}
public static void SetInheritedValue(DependencyObject target, int value)
{
   target.SetValue(InheritedValueProperty, value);
}
public int InheritedValue
{
   get
   {
      return GetTimeSlotDuration(this);
   }
   set
   {
      SetTimeSlotDuration(this, value);
   }
}

子对象将使用 AddOwner 定义具有继承值的属性实例。以下是进入 MyChildClass 示例类的代码:

public static readonly DependencyProperty InheritedValueProperty;
public int InheritedValue
{
   get
   {
      return (int)GetValue(InheritedValueProperty);
   }
   set
   {
      SetValue(InheritedValueProperty, value);
   }
}
static MyChildClass()
{
   InheritedValueProperty = 
       MyClass.InheritedValueProperty.AddOwner(typeof(MyChildClass),
           new FrameworkPropertyMetadata(0,
                   FrameworkPropertyMetadataOptions.Inherits));
}

如果使用单参数重载,则保留全局默认值并且继承仍然有效...

MyClass.InheritedValueProperty.AddOwner(typeof(MyChildClass));

请注意,该属性位于声明为标准依赖属性的子类中,并且它在元数据选项中指定了继承。

现在有了这样的设置,当 MyChildClass 在视觉上或逻辑上是 MyClass 的父级时,它们将自动共享相同的属性值。

所以从技术上讲,你在可视化树中看到的就是你告诉它做的事情。它设置了您告诉它的默认值,并且继承的控件继承自您的 ContentPresenter 父项的值

【讨论】:

  • 您能否澄清一下,最后一句中的“继承的控件”是什么意思?无论如何,我的问题是为什么 ControlPresenter 继承了该值,而 DesignerItemsPresenter 没有。不以任何方式从设置值的 HeaderedDesignerItemChrome 中“继承”。
  • 是否有权假设控件可能不会继承树中较高位置设置的可继承依赖属性的值,除非它被添加为该属性的所有者(调用 AddOwner)?
  • @EugeneStrizhok 是的,除非它在其静态构造函数中显式调用该类,并且您告诉它继承 dependencyproperty 以从基类继承,否则它不会从树继承更高。请参阅我给您的示例代码中的static constructor
  • 但在这种情况下,它永远不会奏效!在我的控制和另一个我的控制之间可能会有另一个标准或第 3 方控制。按照这个逻辑,它们不会继承该值,因此,我也不会在它们下面进行控制。我不明白...
  • 无论如何,我尝试调用 AddOwner。没什么区别。
【解决方案2】:

消除两个 ContentPresenter 中的一个(在 DesignerItemsPresenter 上方的两个屏幕截图中可见)对我有用。我倾向于认为这是 WPF 框架本身的一个错误。

【讨论】:

    猜你喜欢
    • 2013-04-01
    • 1970-01-01
    • 2013-04-01
    • 1970-01-01
    • 2011-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-07
    相关资源
    最近更新 更多