我有一个带有节点层次结构的 WPF 树视图的应用程序。我必须为一个或多个选定节点显示上下文菜单。When one or more nodes are selected, a collection in my viewmodel gets populated with all those selected nodes.
我有一组绑定到我的树视图上下文菜单的菜单项。我只希望在用户右键单击节点(或节点)时评估此绑定。
在这里更具体一点是我想要的:
- 用户单击一个或多个菜单项以选择它们
- 他右键单击以调出上下文菜单,我需要在此时评估我的上下文菜单竞价(MenuItems),而不是在用户单击每个菜单项时进行评估,就像现在发生的那样。
下面是我的代码:
<TreeView MinWidth="100" ItemsSource="{Binding Nodes}">
<i:Interaction.Behaviors>
<Behaviors1:BindableSelectedItemBehavior SelectedItem="{Binding SelectedItem, Mode=TwoWay}" />
</i:Interaction.Behaviors>
<TreeView.ContextMenu>
<ContextMenu ItemsSource="{Binding MenuItems}" Visibility="{Binding ShowContextMenu, Converter={StaticResource VisibilityConverter}}">
<ContextMenu.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Header" Value="{Binding Name}"/>
<Setter Property="IsEnabled" Value="{Binding IsEnabled}"/>
<Setter Property="Command" Value="{Binding MenuCommand}"/>
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>
</TreeView.ContextMenu>
</TreeView>
我的视图模型:
internal class MyViewModel : NotificationObject
{
private readonly IContextMenuProvider _contextMenuProvider;
public MyViewModel(IContextMenuProvider contextMenuProvider)
{
_contextMenuProvider = contextMenuProvider;
}
public ObservableCollection<IMenuItem> MenuItems
{
get
{
System.Diagnostics.Debug.WriteLine("Getting menu items");
return GetMenuItems();
}
}
private ObservableCollection<INodeViewModel> _selectedNodes;
public ObservableCollection<INodeViewModel> SelectedNodes
{
get { return _selectedNodes; }
set
{
_selectedNodes = value;
System.Diagnostics.Debug.WriteLine("Setting selected nodes");
foreach (var nodeViewModel in _selectedNodes)
{
System.Diagnostics.Debug.WriteLine(nodeViewModel.Name);
}
RaisePropertyChanged(() => SelectedNodes);
RaisePropertyChanged(() => ShowContextMenu);
RaisePropertyChanged(() => MenuItems);
}
}
public bool ShowContextMenu
{
get
{
var canDisplay = _contextMenuProvider.GetMenuItemsByNodeContext(SelectedNodes);
return !canDisplay.IsNullOrEmpty();
}
}
private ObservableCollection<IMenuItem> GetMenuItems()
{
var items = _contextMenuProvider.GetAllMenuItems(SelectedNodes);
var menuItems = new ObservableCollection<IMenuItem>(items);
return menuItems;
}
}
我面临的问题是:我不知道应该在什么时候获取菜单项,我应该在填充 selectednodes 集合时还是在用户右键单击时这样做?我希望在右键单击期间理想地发生其中任何一个,请问如何在右键单击树视图上的节点时刷新树视图上下文菜单绑定?
注意:我在 NodeViewModel 上有一个 selected 属性用于选择目的。
谢谢,-迈克