2011-07-26 36 views
5

如何获取ContextMenu中UserControl的原始DataContext。在ContextMenu中访问ViewModel/DataConext

下面的代码,你可以看到DataTemplate中有一个Button,它可以正确绑定。但是,当试图绑定上下文菜单的数据源时,我收到以下错误:

System.Windows.Data错误:4:找不到与参考'RelativeSource FindAncestor,AncestorType ='System.Windows绑定的源。 Controls.TreeView',AncestorLevel ='1''。 BindingExpression:路径= DataContext的;的DataItem = NULL;目标元素是'ContextMenu'(Name ='');目标属性是'DataContext'(类型'对象')

我需要做什么才能让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; 
    .... 
} 

回答

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隧道。只有一种方式来做到这一点(至少我希望它的作品),我也看到了一些图书馆,弥合这种差距,但我不记得他们的起源...

+0

这很好!谢谢!你提到了可能弥补这个差距的其他图书馆,棱镜会是其中之一吗? –

+0

很高兴帮助:)我不知道棱镜是否有支持,我只是再次环顾四周,[this](http://www.codeproject.com/KB/WPF/AttachingVirtualBranches.aspx)将是其中之一这些图书馆我早先来过,但我不知道它是否会在这种情况下工作,因为我认为我从来没有真正使用它。然而,我在一段时间之前尝试了另一种名为[DataContextSpy](http://www.codeproject.com/KB/WPF/ArtificialInheritanceCxt.aspx)的东西,但它对我来说没有什么用处,也许我错误地应用了它。 ... –

+0

标签属性是我失踪!谢谢! –