如何在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;
....
}
答案 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
进行隧道传输。只有一种方法(至少我希望它有效),我也看到一些图书馆以不同的方式弥合这个差距,但我不记得它们的起源...