网格内的 ContentPresenter 可见性绑定不起作用?
Posted
技术标签:
【中文标题】网格内的 ContentPresenter 可见性绑定不起作用?【英文标题】:ContentPresenter Visibility binding inside Grid not working? 【发布时间】:2013-12-21 01:54:52 【问题描述】:我有以下网格:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
...
<ContentPresenter Grid.Row="1" Content="Binding Path=PredictiveWorkspace"
Visibility="Binding Path=ShowPredictiveWorkspace,
Converter=StaticResource boolToVisibility"/>
<ContentPresenter Grid.Row="1" Content="Binding Path=M2Workspace"
Visibility="Binding Path=ShowStandardWorkspace,
Converter=StaticResource boolToVisibility"/>
...
</Grid>
这两个ContentPresenters
具有相同的Grid.Row
定义,因为一次只能看到其中一个。
我有以下boolToVisibility
转换器:
[ValueConversion(typeof(bool), typeof(System.Windows.Visibility))]
public class BoolToVisibilityConverter : IValueConverter
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
if ((bool)value)
return System.Windows.Visibility.Visible;
else
return System.Windows.Visibility.Collapsed;
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
return null;
问题是:ContentPresenters
都是可见的!我还注意到只有ShowPredictiveWorkspace
属性被应用程序读取。在ShowStandardWorkspace
getter 上设置的断点永远不会被调用。
我猜这是一个愚蠢的错误,但我真的找不到它。
编辑:
public bool ShowStandardWorkspace
get return this._showStandardWorkspace;
set
this._showStandardWorkspace = value;
this.OnPropertyChanged(() => this.ShowStandardWorkspace);
【问题讨论】:
这可能与开始时M2Workspace
为空有关吗?我认为 ContentPresenter 的可见性不应该与其呈现的内容相关,对吗?
您可以通过将两个演示者绑定到相同的内容来验证此假设。
【参考方案1】:
可能的错误来源:
拼写错误 ShowStandardWorkspace 属性设置器中未引发 OnPropertyChanged("ShowStandardWorkspace") ShowStandardWorkspace 属性根本没有设置为 false 可能是第二个 ContentPresenter 的 DataContext 错误【讨论】:
我查过了。 1. 拼写错误 - 不是,我全部复制/粘贴了。 2. OnPropertyChanged 被提出,更多的是 - 处理程序不为空,所以绑定了对吗? 3. 是假的。 4. 如果上下文与第一个 ContentPresenter 在同一个视图模型中并且它是同一个视图,那么上下文怎么可能是错误的? 那么它应该可以工作 :) 你能在运行时用 Snoop 检查绑定吗? 感谢有关 Snoop 的提示,非常有趣的应用程序。我之前也在同一个视图中使用boolToVisibilityConverter
,我注意到 Snoop 中的“可见性”属性以绿色突出显示。但是 - 在两个有问题的ContentPresenters
中 - 它都以红色突出显示。诡异的。我得再仔细看一遍。【参考方案2】:
您应该使用AncestorType
。 DataContext 不一样,当您使用 ContentPresenter 时,您可以在 Visual Tree 中向上导航以找到它。在你的情况下:
Visibility="Binding RelativeSource=RelativeSource AncestorType=x:Type Grid, Path=ShowStandardWorkspace"
默认情况下,Grid 是第一个祖先,使用它的DataContext
。如果您需要第二个、第三个等祖先,请使用 AncestorLevel
属性和 int
值。
我认为转换器很好。
【讨论】:
嗯,这不是真的。 @Somedust - 你是对的。鲁道夫金写的不是真的。我检查了(以防万一),但很明显,因为第一个 contentpresenter 读取属性没有问题。【参考方案3】:我已经搜索了很多,而且我做了一些测试,我很确定你无法控制 contentpresenter 的可见性。另外 - 如果在显示视图时将由 ContentPresenter
呈现的 ViewModel 为空 - 它甚至不会读取 boolToVisibilityConverter
使用的属性。
我做了一个简单的解决方法 - 我将 ContentPresenter
放在 Grid
中(您显然可以使用其他类型的容器)并将 Grid
的 Visibility
绑定到布尔属性。效果很好。
【讨论】:
一般来说,您可以控制 ContentPresenter 的可见性。问题是设置 Content 属性也会将 ContentPresenter 的 DataContext 设置为相同的值,从而破坏了所有期望 DataContext 从父控件继承的绑定。【参考方案4】:这是因为将可见性与 ContentPresenter
元素上的转换器绑定不起作用。
如果您将ContentPresenter
更改为ContentControl
,它将可以将可见性属性与转换器绑定,然后您不必将其嵌套在另一个元素中。
这显然是因为ContentPresenter
是一个轻量级元素,旨在用于ControlTemplate
。
From MSDN(我的突出显示):
您通常在 ControlTemplate 中使用 ContentPresenter ContentControl 指定要添加内容的位置。每一个 ContentControl 类型默认有一个 ContentPresenter 控制模板。
当 ContentPresenter 对象位于 ContentControl 的 ControlTemplate、Content、ContentTemplate 和 ContentTemplateSelector 属性从 ContentControl 的同名属性。你可以拥有 ContentPresenter 属性从中获取这些属性的值 通过设置 ContentSource 模板化父级的其他属性 属性或绑定到它们。
【讨论】:
以上是关于网格内的 ContentPresenter 可见性绑定不起作用?的主要内容,如果未能解决你的问题,请参考以下文章