Wpf TreeView与MVVM中的动态上下文菜单

Wpf TreeView与MVVM中的动态上下文菜单,wpf,mvvm,treeview,contextmenu,Wpf,Mvvm,Treeview,Contextmenu,我有一个ViewModels树显示为TreeView(使用HierarchycalDataTemplate)。每个ViewModel实例都有可以在其上执行的不同命令,这些命令再次显示为每个项ViewModel的命令ViewModels列表。如何创建一个单个上下文菜单,该菜单在右键单击的TreeViewItem处打开,并从基础项ViewModel的命令ViewModels列表中填充其命令?所有这些都以一种体面的MVVM方式…我想我理解你的问题。我认为您可以这样构造视图模型: interface I

我有一个ViewModels树显示为TreeView(使用HierarchycalDataTemplate)。每个ViewModel实例都有可以在其上执行的不同命令,这些命令再次显示为每个项ViewModel的命令ViewModels列表。如何创建一个单个上下文菜单,该菜单在右键单击的TreeViewItem处打开,并从基础项ViewModel的命令ViewModels列表中填充其命令?所有这些都以一种体面的MVVM方式…

我想我理解你的问题。我认为您可以这样构造视图模型:

interface ICommandViewModel : ICommand
{
  string Name {get;}
}

interface INodeViewModel
{
  IEnumerable<ICommandViewModel> CommandList {get;}
}

public class NodeViewModel : INodeViewModel
{
  public NodeViewModel()
  {
    //Init commandList
    //Populate commandList here(you could also do lazy loading)
  }

  public NodeViewModel(IEnumerable<ICommandViewModel> commands)
  {
    CommandList = commands;
  }

  public IEnumerable<ICommandViewModel> CommandList {get;private set;}
}
界面ICommandViewModel:ICommand { 字符串名称{get;} } 接口索引设备模型 { IEnumerable命令列表{get;} } 公共类nodevewmodel:INodeViewModel { 公共节点设备模型() { //初始化命令列表 //在这里填充commandList(您也可以进行延迟加载) } 公共节点设备模型(IEnumerable命令) { CommandList=命令; } 公共IEnumerable命令列表{get;private set;} } 然后在xaml中

<TreeViewItem>
  <TreeViewItem.ContextMenu Items={Binding CommandList}>
    <ContextMenu.ItemTemplate>
      <DataTemplate>
        <MenuItem Header="{Binding Name}" Command="{Binding}"/>
      </DataTemplate>
    </ContextMenu.ItemTemplate>
  </TreeViewItem.ContextMenu>
</TreeViewItem>

我对分层数据模板没有太多经验,但您可以从上面得到要点。您也可以使用中的样式执行上述操作,但我面前没有xaml编辑器来提供正确的语法


希望这对我有帮助

当我有一棵包含大量项目的hughe树时,它不会创建数千个上下文菜单吗?那不是个问题吗?我只需要一个上下文菜单,可以根据当前项目更改其内容。就我个人而言,我不会担心它,除非你注意到性能命中。我怀疑它会。但另一种选择是在TreeView ViewModel中有一个IEnumerable,该IEnumerable动态填充选定的NodeView模型。但是,您需要存储所选的一个,以便可以填充它的ICommands。我不认为复杂性值得这么做。我不知道一个MenuItem控件的内存足迹,但假设它是1KB(可能很高),其中一千个只有1MB。我认为你不应该为此担心。另外,WPF可能会延迟加载菜单项,因此可能只有右键单击的节点才会占用内存。