【问题标题】:ContentPresenter Visibility binding inside Grid not working?网格内的 ContentPresenter 可见性绑定不起作用?
【发布时间】: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 的可见性不应该与其呈现的内容相关,对吗?
  • 您可以通过将两个演示者绑定到相同的内容来验证此假设。

标签: wpf grid converter visibility 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 中(您显然可以使用其他类型的容器)并将 GridVisibility 绑定到布尔属性。效果很好。

【讨论】:

  • 一般来说,您可以控制 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 模板化父级的其他属性 属性或绑定到它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-24
    • 2011-05-30
    • 2017-07-14
    • 2017-11-09
    • 2017-04-19
    • 2014-09-05
    相关资源
    最近更新 更多