6
votes

I have a tree of ViewModels displayed as a TreeView (using HierarchicalDataTemplate). Each ViewModel instance has different commands that can be executed on it wich again are exposed as a list of command ViewModels for each item ViewModel. How can I create a single ContextMenu that opens at the TreeViewItem that was rightclicked and that populates its commands from the underlying item ViewModel's command ViewModels list? All in a decent MVVM fashion ...

1

1 Answers

3
votes

I think I understand your question. I think that you could structure your ViewModels like this:

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;}
}

and then in xaml

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

I don't have much experience with hierarchical datatemplate but you get the gist from the above. You could also do the above with a style in the but I don't have a xaml editor in front of me to give you right syntax.

Hope that helps