【问题标题】:Bind to Page's DataContext绑定到页面的 DataContext
【发布时间】:2015-07-14 06:21:48
【问题描述】:

我发现需要绑定到 PageDataContext,设置如下:

<d:Page.DataContext>
    <designTime:PayeesPageDesignViewModel />
</d:Page.DataContext>

在设计时。但是,我需要从具有不同数据上下文的子控件绑定到它:

<GridView x:Name="PayeesGridView"
          Margin="0,30,0,0"
          IsItemClickEnabled="True"
          ItemsSource="{Binding Payees}"
          SelectionChanged="PayeesGridView_OnSelectionChanged">

由于为GridView 设置了ItemsSource,因此我的GridViewItemsDataContext 设置为Payee 集合中的单个Payee 对象。我的ViewModel 有一个属性,我需要从转换器中的View 引用该属性以确定项目的可见性。

我可以根据Payee 对象的属性设置可见性,如下所示:

<Border Width="250"
        Height="250"
        Background="Gray"
        Opacity="0.85"
        Visibility="{Binding Path=IsOpen,
                     Converter={StaticResource AccountStatusToVisibilityConverter}}">

但我真正需要绑定的是PageDataContextSettings.ShowInactive 属性。有没有办法从子控件中获取该上下文?我使用的是 WinRT,所以我没有 FindAncestor 绑定源的好处。

编辑

按照 cmets 中的建议,我尝试将绑定更改为如下所示:

Visibility="{Binding Path=DataContext.Settings.ShowInactivePayees, ElementName=PageName,
             Converter={StaticResource AccountStatusToVisibilityConverter}}">

但是当我在AccountStatusToVisibilityConverter 中设置断点时,转换器永远无法到达。

【问题讨论】:

  • 给页面一个x:Name并使用ElementName绑定?
  • 啊,谢谢。我知道有办法做到这一点,但我想不通。这就是我在半夜编程所得到的:)我正在尝试绑定ElementName="PageName.DataContext"Path="Settings.ShowInactivePayees",但被传递的是null,即使DesignTimeViewModel被硬编码为false和我在运行时尝试将ShowInactivePayees 设置为truefalse
  • PageName.DataContext 不是元素名称。你的绑定应该看起来像{Binding Path=DataContext.Settings.ShowInactive, ElementName=PageName}
  • 我以为ElementName="PageName.DataContext" Path="Settings.ShowInactivePayees"ElementName="PageName" Path="DataContext.Settings.ShowInactivePayees" 是一样的?无论如何,无论ShowInactivePayees 的值如何,我仍然将null 作为传递的值。
  • 我在我的问题中添加了绑定现在的样子。现在转换器甚至没有启动。我正在设置 x:Name="PageName" 并且编译器正在识别所有内容,但我不明白为什么转换器不再触发。

标签: c# xaml windows-runtime winrt-xaml


【解决方案1】:

你是如何在 GridView 中分配 ItemTemplate 的?如果您更改了整个模板而不是修改模板的内容,该怎么办?就像这个伪 xaml...

<Page.Resources>
    <DataTemplate x:Key="ActiveTemplate"></DataTemplate>
    <DataTemplate x:Key="InactiveTemplate"></DataTemplate>
    <local:IsActiveToItemTemplateConverter x:Key="IsActiveToTemplate"
        ActiveTemplate="{StaticResource ActiveTemplate}"
        InactiveTemplate="{StaticResource InactiveTemplate}"
        />
</Page.Resources>

<GridView
    ItemsSoucre="{Binding Payees}"
    ItemTemplate="{Binding Settings.ShowInactive, Converter={StaticResource IsActiveToTemplate}}"
    IsItemClickEnabled="{Binding Settings.ShowInactive, Converter={StaticResource BooleanNot}}"
    />

【讨论】:

  • 我喜欢这个主意。今晚下班回家后,我会尝试这样的事情。谢谢你的建议。我没有意识到我可以有单独的模板。
  • 有没有办法设置各个模板的DataContext?一切都正确绑定,但 ReSharper 不喜欢所有未解析的属性。它认为DataContext 是页面的上下文而不是GridViewItemsSource
  • 在列表中创建的每个项目都将具有其特定列表项目的 DataContext ...因此是“收款人”。应用程序代码无法修改将分配为 DataContext 的对象,因为这一切都发生在 GridView 的私有代码中。我认为您的项目不应与 Page 的 DataContext 对话。这似乎是一个等待咬你的维护问题。但是,如果必须,您始终可以让每个 Payee 对象都有一个指向 Page 的 ViewModel 的属性,并在创建 Payee 对象时设置该属性。然后您就可以在项目内部轻松访问它了。
  • 我认为这很好。我在&lt;Page.Resources&gt; 的顶部定义了模板,在&lt;GridView&gt; 知道它的ItemsSource 将是什么之前。 ReSharper 只是感到困惑,因为它不知道模板将与Payee 对象相关联。我只是在寻找能够在模板中指定它以实现自动完成目的的东西,并避免来自 ReSharper 的任何波浪线:)
  • 但是在运行时,两个不同的模板都能正常工作。这只是设计时的问题,因为 ReSharper 无法推断出 DataContext..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-02-02
  • 2011-10-13
  • 1970-01-01
  • 2015-01-21
  • 2011-05-19
  • 2011-10-17
  • 2016-09-06
相关资源
最近更新 更多