如何将DataContext绑定到窗口资源中的ViewModel对象

3
我正在尝试将我的用户控件数据上下文绑定到视图模型对象。由于某种未知的原因,在Window.Resources内设置DataContext会导致以下错误:

System.Windows.Data Error: 3 : 无法找到提供DataContext的元素。BindingExpression:Path=AreaFilter; DataItem=null;

在窗口资源之外设置相同的数据上下文则完美地工作。以下代码片段应该能够澄清事情:
<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是一个用户控件,我目前简化了它只显示一个文本块。 在Grid中,它可以轻松地显示AreaFilter.Name。 在这两种情况下设置DataContext有何不同,如何解决?


绑定的使用方式如此,它引用另一个DataContext。因此,即使您设置了DataContext,您仍需要另一个有效的DataContext才能从中获取属性AreaFilter。 - dowhilefor
1个回答

2

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

您可以尝试使用引用您的GridViewRelativeSource绑定来设置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>

您可以在此处查看此示例的实现

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


我不确定我是否清楚地理解了它。我正在尝试在不同的列中使用<v:FilterV>(在示例中,我简化了代码),并且在每个列中,它必须绑定到不同的对象。这就是为什么我试图在ColumnCollection中设置DataContext。如果我定义一个包含v:FilterV的DataTemplate,我不知道在哪里将不同的VM对象绑定到每个FilterV。 - Bartek
好时机,这似乎与我刚刚在这里提出的问题类似。希望你的答案能为我的问题提供一些启示! - HolySamosa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接