我有一个以下网格:
<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);
}
}
答案 0 :(得分:9)
这是因为它无法将可见性与ContentPresenter
元素上的转换器绑定。
如果将ContentPresenter
更改为ContentControl
,则可以将visibility属性与转换器绑定,然后您不必将其嵌套在另一个元素中。
这显然是因为ContentPresenter
是一个轻量级元素,意在ControlTemplate
中使用。
From MSDN(突出显示):
您通常在a的ControlTemplate中使用ContentPresenter ContentControl 指定要添加内容的位置。一切 ContentControl类型默认具有ContentPresenter 控件模板。
当ContentPresenter对象在。时 ContentControl的ControlTemplate,Content,ContentTemplate和 ContentTemplateSelector属性从中获取它们的值 ContentControl的相同名称的属性。你可以拥有 ContentPresenter属性从中获取这些属性的值 通过设置ContentSource,模板化父级的其他属性 财产或与他们绑定。
答案 1 :(得分:3)
我一直在搜索很多,而且我做了一些测试,我很确定你无法控制contentpresenter的可见性。另外 - 如果在显示视图时由ContentPresenter
呈现的ViewModel为null,则它甚至不会使用boolToVisibilityConverter
来读取属性。
我做了一个简单的解决方法 - 我将ContentPresenter
置于Grid
(显然可以使用其他类型的容器)并将Visibility
的{{1}}绑定到布尔值属性。它运作得很好。
答案 2 :(得分:1)
您应该使用AncestorType
。使用ContentPresenter时,DataContext不相同,但您可以在Visual Tree中向上导航以查找它。在你的情况下:
Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type Grid}}, Path=ShowStandardWorkspace}"
默认情况下,Grid是第一个祖先,并使用其DataContext
。如果您需要第二个,第三个等祖先,请使用AncestorLevel
属性int
。
我认为转换器很好。
答案 3 :(得分:0)
可能的错误来源: