访问ContextMenu中的ViewModel / DataConext

时间:2011-07-26 00:28:13

标签: c# wpf data-binding 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>

视图模型:

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;
    ....
}

1 个答案:

答案 0 :(得分: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}" />
            <!-- ... --->

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