WPF覆盖父级的IsEnabled [英] WPF override IsEnabled from Parent

查看:163
本文介绍了WPF覆盖父级的IsEnabled的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是在寻找一种在父控件具有 IsEnabled = false 时启用子控件的方法。
我到目前为止发现的所有答案都说这是不可能的-除了必须仍然启用的控件之外,必须启用父控件并禁用子控件。

I just searched for a way to enable a child control while the parent control has IsEnabled = false. All answers that I have found up to now say that it is not possible - one has to enable the parent and disable the child controls except the ones that should still be enabled.

但是,通过覆盖App.xaml.cs文件中IsEnabledProperty的元数据,我能够更改此默认行为:

However, by overriding the Metadata for the IsEnabledProperty in the App.xaml.cs file, I was able to change this default behavior:

protected override void OnStartup(StartupEventArgs e)
{
    UIElement.IsEnabledProperty.OverrideMetadata(typeof(FrameworkElement),
             new UIPropertyMetadata(true,IsEnabledChanged, CoerceIsEnabled));
}

private void 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 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;
}

现在您可以手动设置 IsEnabled 属性会覆盖父级值。

Now you can manually set the IsEnabled property on a child, which overrides the parent value.

此方法是否有缺点?

推荐答案

这在我使用了几次修改后的控件的情况下适用于我的情况。

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:


  • 将其放置在静态构造函数中而不是事件中,否则它将尝试对其进行多次设置并抛出 PropertyMetadata已被注册为'{type}'类型。

  • 更改了类型以匹配控件

代码:

请确保找到 [CustomControl] 并将其替换为控件的类型名称。

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;
}

这篇关于WPF覆盖父级的IsEnabled的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆