【问题标题】:How to bind DataContext to ViewModel object in window resources如何将 DataContext 绑定到窗口资源中的 ViewModel 对象
【发布时间】:2012-09-05 13:55:36
【问题描述】:

我正在尝试将我的用户控件数据上下文绑定到视图模型对象。由于未知原因,在 Window.Resources 中设置 DataContext 结果给出了

System.Windows.Data 错误:3:找不到提供的元素 数据上下文。绑定表达式:路径=区域过滤器;数据项=null;

在 window.resources 之外设置相同的数据上下文非常完美。一段代码应该可以解决问题:

<Window>
<Window.Resources>
    <GridViewColumnCollection x:Key="eventColumns">
        <GridViewColumn DisplayMemberBinding="{Binding Path=Area}">
            <GridViewColumn.Header>
                <v:FilterV DataContext="{Binding AreaFilter}"/> <!--here is the problem-->
            </GridViewColumn.Header>
        </GridViewColumn>
    </GridViewColumnCollection>
</Window.Resources>
<Grid>
    <v:FilterV DataContext="{Binding AreaFilter}"/> <!-- here it works OK -->
    <GridViewHeaderRowPresenter Name="listHeader" Columns="{StaticResource eventColumns}"/>
</Grid>

FilterV 是我目前简化为仅显示文本块的 UserControl。 在 Grid 内,它显示 AreaFilter.Name 没有问题。 这两种情况下设置DataContext有什么区别,如何解决?

【问题讨论】:

  • 这样使用的绑定是指另一个DataContext。所以即使你设置了DataContext,你也需要有另一个有效的DataContext才能从中获取属性AreaFilter。

标签: wpf mvvm binding datacontext


【解决方案1】:

我相信GridViewColumn 实际上并不是VisualTree 的一部分,因此其中的绑定不起作用,因为它没有DataContext 或评估绑定时使用的源。

您可以尝试使用引用您的GridView 的RelativeSource 绑定来设置DataContext

<GridViewColumn.HeaderTemplate>
    <DataTemplate>
        <v:FilterV DataContext="{Binding DataContext.AreaFilter, 
            RelativeSource={RelativeSource AncestorType={x:Type GridView}}}"/>
    </DataTemplate>
</GridViewColumn.HeaderTemplate>

虽然如果这不起作用,我发现的唯一解决方法是在您的 .Resources 中创建一个包含您正在寻找的绑定的 Freezeable 对象,然后将您的 v:FilterV.DataContext 设置为静态资源

<GridView.Resources>
    <local:BindingProxy x:Key="proxy" 
        Data="{Binding AreaFilter, ElementName=MyGridView}" />
</DataGrid.Resources>

...

<GridViewColumn.HeaderTemplate>
    <DataTemplate>
        <v:FilterV DataContext="{Binding Source={StaticResource proxy}}"/>
    </DataTemplate>
</GridViewColumn.HeaderTemplate>

您可以查看此here的示例

此外,您应该将GridViewHeaderTemplate 属性设置为包含&lt;v:FilterV /&gt; 控件的DataTemplate,而不是像现在这样直接在.Content 属性中设置它。将Content 直接设置为一个对象意味着任何使用该样式的项目都将尝试使用Content 中的相同控件,因此如果您有多个对象应用该Content 属性,它将引发异常因为项目只能属于一个父控件

【讨论】:

  • 我不确定我是否理解清楚。我尝试在不同的列中使用 (在示例中我简化了代码),并且在每一列中它必须绑定到不同的对象。这就是我尝试在 ColumnCollection 中设置 DataContext 的原因。如果我定义一个包含 v:FilterV 的 DataTemplate,我不知道在哪里将不同的 VM 对象绑定到每个 FilterV。
  • 好时机,这似乎与我刚刚问过的问题here 相似。希望您的回答能对我的问题有所启发!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-08
  • 1970-01-01
  • 2015-10-22
  • 1970-01-01
  • 2016-07-11
  • 2016-05-04
  • 1970-01-01
相关资源
最近更新 更多