C# 在ContextMenu中访问ViewModel/DataConText

C# 在ContextMenu中访问ViewModel/DataConText,c#,wpf,data-binding,mvvm,prism-4,C#,Wpf,Data Binding,Mvvm,Prism 4,如何在ContextMenu中获取UserControl的原始DataContext 在下面的代码中,您可以看到DataTemplate中有一个按钮,它可以正确绑定。但是,在尝试绑定contextmenu的数据源时,我收到以下错误: System.Windows.Data错误:4:找不到用于绑定的源,引用为“RelativeSource FindAncestor,AncestorType='System.Windows.Controls.TreeView',AncestorLevel='1'。B

如何在ContextMenu中获取UserControl的原始DataContext

在下面的代码中,您可以看到DataTemplate中有一个按钮,它可以正确绑定。但是,在尝试绑定contextmenu的数据源时,我收到以下错误:

System.Windows.Data错误:4:找不到用于绑定的源,引用为“RelativeSource FindAncestor,AncestorType='System.Windows.Controls.TreeView',AncestorLevel='1'。BindingExpression:Path=DataContext;DataItem=null;目标元素是“ContextMenu”(名称=“”);目标属性为“DataContext”(类型为“Object”)

我需要做什么才能允许ContextMenu绑定到ViewModel

===============================================================================

ViewModel分配给codebehind中视图的datacontext:

查看:

<TreeView ItemsSource="{Binding Clients}"
          cmd:TreeViewSelect.Command="{Binding SelectionChangedCommand}"
          cmd:TreeViewSelect.CommandParameter="{Binding RelativeSource={RelativeSource Self},Path=SelectedItem}">
    <TreeView.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding Name}">
                    <TextBlock.ContextMenu>
                        <ContextMenu DataContext="{Binding DataContext, 
                            RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TreeView}}}">
                            <MenuItem Header="{Binding TestString}" />
                        </ContextMenu>
                    </TextBlock.ContextMenu>
                </TextBlock>

                <Button  DataContext="{Binding DataContext, 
                            RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TreeView}}}"
                         Content="{Binding TestString}" Command="{Binding EditSelectedClientCommand}" />
             </StackPanel>
        </DataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

contextmenu
不会出现在可视化树中,这会导致相对资源绑定失败,但您仍然可以通过某种方式获得
DataContext
。您可以尝试以下示例:

<TextBlock Text="{Binding Name}"
           Tag="{Binding DataContext, RelativeSource={RelativeSource AncestorType=TreeView}}">
    <TextBlock.ContextMenu>
        <ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
            <MenuItem Header="{Binding TestString}" />
            <!-- ... --->


PlacementTarget
是文本块,
DataContext
通过
标记进行隧道传输。只有一种方法可以做到这一点(至少我希望它能起作用),我也看到一些图书馆以不同的方式弥补了这一差距,但我不记得它们的起源…

这非常有效!非常感谢。你提到了其他可能弥补这一差距的库,Prism会是其中之一吗?很高兴它起到了帮助:)我不知道Prism是否支持这一点,我只是再次环顾四周,并将成为我之前访问过的库之一,但我不知道它在这种情况下是否有效,因为我认为我从未实际使用过它。然而,我不久前尝试了另一种叫做的东西,但它对我没有多大用处,也许我应用错了……Tag属性就是我所缺少的!非常感谢。
<TextBlock Text="{Binding Name}"
           Tag="{Binding DataContext, RelativeSource={RelativeSource AncestorType=TreeView}}">
    <TextBlock.ContextMenu>
        <ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
            <MenuItem Header="{Binding TestString}" />
            <!-- ... --->