简体   繁体   中英

How to stop WPF Property Value Inheritance propagation at certain boundaries

I have an attached property that specifies the "inherits" option to achieve WPF property value inheritance. I can see that the property value is propagated across the visual tree. However, with large visual trees, this may impact performance quite a bit.

I would therefore like the attached property value inheritance of my attached property to stop at certain boundaries, more specifically instances of a particular class.

I have read about FrameworkElement.InheritanceBehavior, which a control can set to something like SkipAllNext, which stops property value inheritance (for all properties, though), but also affects resource lookup. The effect on resource lookup is not desirable.

Is there any other way to control the propagation, either in the attached property or in the class that should act as a boundary?

What I am trying to achieve is here: WPF container to turn all child controls to read-only . The solution with value inheritance to have all controls in a form turn to read-only based on a global switch is pretty good. It just has the performance penalty as mentioned there and here.

AddOwner seems to work:

class BoundaryElement : FrameworkElement {
    public static readonly DependencyProperty CustomProperty =
        AttachedProperties.CustomProperty.AddOwner(typeof(BoundaryElement),
            new FrameworkPropertyMetadata() {Inherits = false});
}

I tried setting Inherits = false through OverrideMetadata , but this will only affect the BoundaryElement itself, and the attached property value continues to propagate to its children. AddOwner effectively replaces the property at the BoundaryElement so that the original doesn't exist to inherit from.

There is one possibility that I know about. It's not really what you're after, but you can use the DependencyProperty.OverrideMetadata Method to override the PropertyMetadata of the DependencyProperty in an extended control:

public class SomeControl : OriginalControl
{
    static SomeControl()
    {
        OriginalControl.SomeProperty.OverrideMetadata(typeof(SomeControl), 
            new FrameworkPropertyMetadata(defaultValue, 
            FrameworkPropertyMetadataOptions.OverridesInheritanceBehavior));
    }
}

Apart from this, (I could be wrong but) I don't think that you'll be able to achieve your goal... WPF just wasn't designed like that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM