在ContextMenu中访问ViewModel / DataConext
本文关键字:DataConext ViewModel 访问 ContextMenu | 更新日期: 2023-09-27 18:03:35
如何在ContextMenu中获得UserControl的原始DataContext。
在下面的代码中,您可以看到DataTemplate中有一个Button,它正确地绑定了。但是,当尝试绑定上下文菜单的数据源时,我收到以下错误:System.Windows。数据错误:4:找不到绑定引用'RelativeSource FindAncestor, AncestorType='System.Windows.Controls '的源。TreeView",AncestorLevel ="1"。BindingExpression:路径= DataContext;DataItem =零;目标元素是'ContextMenu' (Name= ");目标属性为"DataContext"(类型为"Object")
我需要做什么来允许ContextMenu绑定到ViewModel?
===============================================================================
ViewModel在代码后面被分配给视图的数据上下文:
视图:
<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>
ViewModel:
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;
....
}
ContextMenus
没有出现在导致relativessource绑定失败的可视化树中,但是您仍然可以以某种方式获得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
隧道。只有一种方法可以做到这一点(至少我希望它能起作用),我也看到一些库以不同的方式弥合了这个差距,但我不记得它们的起源…