【发布时间】:2014-03-07 11:32:54
【问题描述】:
我刚刚搜索了一种在父控件具有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 属性,它会覆盖父级值。
这种方法有什么缺点吗?
【问题讨论】:
-
当父级禁用时启用子级 = 子级不应是该父级的子级,设计需要重新考虑。
-
我认为有必要提出另一个问题,以便我们可以告诉您如何使用当前布局来避免这种情况。
-
没有单一的布局可以应用,而是整个应用程序的一般要求。根据当前用户,某些内容不应该是可编辑的。但是,应该可以在子控件中滚动和导航。因此,应启用选定的子控件(例如 TreeView)。实现这一点的最简单方法是禁用父控件并启用选定的子控件 - 否则我们将不得不手动绑定数百个具有不同视图模型的子控件 - 不是每个都自己知道它是否已启用...
-
根据 WPF 中的设计,所有子控件都从父控件继承 isEnable 属性,因此如果该属性与父属性不匹配,则每个子控件都不允许您更改此属性。我确信还有另一种方法可以获得您需要的相同效果(也许还有一些设计更改:),但通过尝试与子 IsEnable 属性不匹配不是正确的方法。如果您可以发布更多的 GUI 设计代码会更好。
-
我也在 VS2013 中使用了这个。我只需要我的应用程序的一个窗口中的行为。因此,我将代码放入 Behaviour
类中。使用此类,可以仅在需要时将行为附加到 UIElement。工作完美。谢谢!
标签: c# wpf dependency-properties