WPF override IsEnabled from Parent

和自甴很熟 提交于 2019-12-03 11:24:27
user1568891

This worked for my situation on a control used several times with some slight modifications.

Placing here to help any future web searchers in a similar situation:

  • placed it in a static constructor instead of an event, otherwise it tried to set it multiple times and threw a "PropertyMetadata is already registered for type '{type}'." exception.
  • Changed the type to match the control

Code:

Make sure to find and replace [CustomControl] with the type name of your control.

static [CustomControl]()
{
    UIElement.IsEnabledProperty.OverrideMetadata(typeof([CustomControl]), new UIPropertyMetadata(true, [CustomControl]_IsEnabledChanged, CoerceIsEnabled));
}

private static void [CustomControl]_IsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var childrenCount = VisualTreeHelper.GetChildrenCount(d);
    for (int i = 0; i < childrenCount; ++i)
    {
        var child = VisualTreeHelper.GetChild(d, i);
        child.CoerceValue(UIElement.IsEnabledProperty);
    }
}

private static object CoerceIsEnabled(DependencyObject d, object basevalue)
{
    var parent = VisualTreeHelper.GetParent(d) as FrameworkElement;
    if (parent != null && parent.IsEnabled == false)
    {
        if (d.ReadLocalValue(UIElement.IsEnabledProperty) == DependencyProperty.UnsetValue)
        {
            return false;
        }
    }
    return basevalue;
}

The drawback is at least, that you break the basic concept, and the IsEnabled is not used for the intended scope. This workaround also makes maintenance a bit more complex (the developer has to understand first, why it works differently).

As it is suggested in comments, I would say, that a redesign of this window would help. Especially, if I would like to forbid only the editing (data modification) in the form, I would use other properties like IsReadOnly.

Another option is to override the FrameworkPropertyMetadataOptions to remove the Inherits property. I had a similar problem with the FontSize and this worked well:

FontSizeProperty.OverrideMetadata(
   typeof(YourControl), 
   new FrameworkPropertyMetadata(8.0, 
      FrameworkPropertyMetadataOptions.None, changed));
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!