我有一个附加的属性,它指定了“inherits”选项来实现WPF属性值继承。我可以看到属性值在整个可视化树中传播。但是,对于大型可视化树,这可能会对性能产生相当大的影响。
因此,我希望我的附加属性的附加属性值继承在某些边界上停止,更具体地说,是特定类的示例。
我读过关于FrameworkElement.InheritanceBehavior的文章,控件可以将其设置为类似SkipAllNext的内容,这会停止属性值继承(尽管对于所有属性),但也会影响资源查找。对资源查找的影响并不理想。
是否有其他方法来控制传播,或者在附加属性中,或者在应该充当边界的类中?
我想达到的目的是:WPF container to turn all child controls to read-only。基于全局开关,通过值继承将窗体中的所有控件变为只读的解决方案非常好。它只是有这里和这里提到的性能损失。
3条答案
按热度按时间quhf5bfb1#
AddOwner似乎可以工作:
我尝试通过
OverrideMetadata
设置Inherits = false
,但这只会影响BoundaryElement
本身,并且附加的属性值会继续传播到其子节点。rn0zuynd2#
我知道有一种可能性。这不是你真正想要的,但你可以使用
DependencyProperty.OverrideMetadata
方法来覆盖扩展控件中DependencyProperty
的PropertyMetadata
:除此之外,(我可能是错的,但)我不认为你能够实现你的目标……WPF只是没有这样设计。
ecbunoof3#
对此的解释有点悲伤和复杂,但幸运的是解决方案非常简单。您不需要使用
AddOwner(...)
。为了在使用
DependencyProperty.OverrideMetadata(...)
时阻止继承,不能使用FrameworkPropertyMetadata
***构造函数***指定FrameworkPropertyMetadataOptions
标志“OverridesInheritanceBehavior
“。原因是,对于某些FPMO标志,默认的FrameworkPropertyMetadata.Merge(...)
函数只处理通过FPM属性设置器显式修改的标志。Inherits
标志/属性是另一个也具有此行为的标志/属性,并且您还需要从任何基本元数据中清除它。因此,使Merge(...)
***清除***结果值(在与基本属性元数据合并后)的唯一方法是再次通过其FPM setter显式设置它。这很令人困惑,不幸的是,这是一个非常不自然/意外/不明显的设计,所以这里有一个例子。假设
SomeDependencyProperty
是bool
属性,基本元数据指定false
的DefaultValue
,并且它启用了DP继承。您希望在派生类MyType
上覆盖默认值true
。因此,在此页面/问题上讨论的整个问题是以下内容不起作用:
如上所述,前面有两个问题,但更明显的一个是,即使
FPMO.OverridesInheritanceBehavior
按预期工作,您也没有***un-set***FPMO.Inherits
标志本身。显然,没有办法通过ORing
和只能Assert的位标志一起取消位标志。所以本质上,在Merge
之后,您将覆盖继承行为--但是继承仍然被启用(由于Merge
)。最后,继承仍然最终被启用,您想要的DefaultValue
基本上没有效果。相反,使用属性setter,如下所示,它可以阻止继承,从而允许修改后的
DefaultValue
生效:引用:Merge(...)@ FrameworkPropertyMetadata. cs