访问ContextMenu中的ViewModel/DataConext

Mic*_*l G 5 c# data-binding wpf mvvm prism-4

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

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

System.Windows.Data错误:4:不能用于与参照结合 '的RelativeSource FindAncestor,AncestorType =' System.Windows.Controls.TreeView找到源 'AncestorLevel = '1''.BindingExpression:路径= DataContext的; 的DataItem = NULL; target元素是'ContextMenu'(Name =''); target属性是'DataContext'(类型'Object')

我需要做什么才能让ContextMenu绑定到ViewModel?

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

ViewModel被分配给代码隐藏中视图的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>
Run Code Online (Sandbox Code Playgroud)

视图模型:

public class ClientListViewModel : ViewModelBase
{
    public String TestString { 
        get {
            return "TESTING";  
        }
    }

    private ClientList _clients = null;
    private readonly IClientService _clientService = null;
    private readonly IEventAggregator _eventAggregator = null;
    private Client _selectedClient = null;
    private ICommand _selectionChangedCommand = null;
    private ICommand _editSelectedClientCommand = null;
    ....
}
Run Code Online (Sandbox Code Playgroud)

H.B*_*.B. 9

ContextMenus如果没有出现在导致RelativeSource绑定失败的可视化树中,您仍然可以通过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}" />
            <!-- ... --->
Run Code Online (Sandbox Code Playgroud)

PlacementTarget是TextBlock,并DataContext通过.net隧道Tag.只有一种方法可以做到这一点(至少我希望它有效),我也看到一些图书馆以不同的方式弥合这个差距,但我不记得它们的起源......