gpt4 book ai didi

c# - WPF 从父级覆盖 IsEnabled

转载 作者:可可西里 更新时间:2023-11-01 07:47:55 45 4
gpt4 key购买 nike

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

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

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 属性,这会覆盖父值。

这种方法有什么缺点吗?

最佳答案

问题中提出的解决方案在某些情况下可能没问题。但是,更改应用程序中所有 UIElement 的默认框架行为可能会引入兼容性问题,并且将来可能很难理解行为更改的位置/原因。

另一种方法是保留框架的默认行为,仅在需要时在特定位置手动覆盖该行为。一种方法是创建一个简单的包装器元素,打破父级的 IsEnabled 继承链。

框架的默认强制回调检查父 IsEnabled 值并继承它。该控件设置了一个新的强制回调,它直接返回值而不检查继承。

public class ResetIsEnabled : ContentControl
{
static ResetIsEnabled()
{
IsEnabledProperty.OverrideMetadata(
typeof(ResetIsEnabled),
new UIPropertyMetadata(
defaultValue: true,
propertyChangedCallback: (_, __) => { },
coerceValueCallback: (_, x) => x));
}
}

可以这样用

<ParentControl IsEnabled="False">
<!-- Any elements here will have IsEnabled set to false, inherited from the parent -->
<ResetIsEnabled>
<!-- Any child elements here will have IsEnabled set to true (the default value) -->
</ResetIsEnabled>
</ParentControl>

关于c# - WPF 从父级覆盖 IsEnabled,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22248943/

45 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com