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 ...
A:
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
Jose
2010-03-25 04:02:04
When I have a hughe tree with lots of items wouldn't that create thousands of contextmenus? Wouldn't that be a problem? I need just one context menu that changes its content based on the current item.
bitbonk
2010-03-27 07:02:17
Personally, I wouldn't worry about it unless you notice a perfomance hit. I doubt it would. But another choice is to have an IEnumerable<ICommand> in your TreeView ViewModel which is dynamically populated with the Selected NodeViewModel. But then you need to store which one's selected so you can populate it's ICommands. I don't think the complexity is worth it.
Jose
2010-03-29 13:28:52
I don't know the memory foot print for one MenuItem control, but let's say it's 1KB(which is probably high) a thousand of those would only be 1MB. I don't think you should worry about it. Plus WPF probably lazy loads the MenuItems anyway, so probably only the nodes that get right-clicked will take memory.
Jose
2010-03-29 13:31:55