WPF覆盖父级的IsEnabled [英] WPF override IsEnabled from Parent
问题描述
我只是在寻找一种在父控件具有 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 $子级的c $ c>属性会覆盖父级值。
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屋!