2010-03-24 6 views
6

У меня есть дерево ViewModels, отображаемое как TreeView (с использованием HierarchicalDataTemplate). Каждый экземпляр ViewModel имеет разные команды, которые могут быть выполнены на нем, которые снова отображаются в виде списка команд ViewModels для каждого элемента ViewModel. Как я могу создать одиночный ContextMenu, который открывается в TreeViewItem, который был правильно выбран, и который заполняет его команды из списка ViewModel в представлении ViewModel? Все в приличной моде MVVM ...динамический ContextMenu в TreeView против MVVM

ответ

3

Я думаю, что я понимаю ваш вопрос. Я думаю, что вы могли бы структурировать ViewModels так:

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

, а затем в XAML

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

У меня нет большого опыта работы с иерархической DataTemplate, но вы получите суть от выше. Вы также можете сделать это со стилем, но у меня нет редактора xaml передо мной, чтобы дать вам правильный синтаксис.

Надеюсь, что поможет

+0

Когда у меня есть дерево hughe с большим количеством предметов, не создало бы тысячи контекстных меню? Разве это не проблема? Мне нужно только одно контекстное меню, которое изменяет его содержимое на основе текущего элемента. – bitbonk

+0

Лично я бы не стал беспокоиться об этом, если вы не заметите удар производительности. Я сомневаюсь. Но другой выбор - иметь IEnumerable в вашем TreeView ViewModel, который динамически заполняется выбранным NodeViewModel. Но тогда вам нужно сохранить выбранный, чтобы вы могли заполнить его ICommands. Я не думаю, что сложность того стоит. – Jose

+0

Я не знаю, как печатают память для одного элемента управления MenuItem, но предположим, что это 1 КБ (что, вероятно, высоко), из них тысяча будет только 1 МБ. Я не думаю, что вам следует беспокоиться об этом. Плюс WPF, вероятно, ленивы загружает MenuItems в любом случае, поэтому, вероятно, только узлы, которые получают щелчок правой кнопкой, будут иметь память. – Jose