创建遵循MVVM范例的菜单栏的最佳方法是什么?

时间:2013-05-14 01:35:45

标签: c# wpf mvvm menu

这是关于SO的第一个问题,所以 Hello

我是WPF的新手,因此我决定尝试为我过去创建的库创建GUI。我想为应用程序创建一个菜单条/行/栏,这对于Menu控件非常简单。但是,我看到了MVVM的提及并进行了查找,并决定我想从一个集合中动态创建菜单。

这一切都很好,我找到了很多关于这个主题的材料,最后得到了我的MenuItems的以下ViewModel:

class MenuItemViewModel
{
    public string Text { get; set; }
    public ICommand Command { get; set; }
    public ObservableCollection<MenuItemViewModel> Children
    {
        get
        {
            return new ObservableCollection<MenuItemViewModel>(children);
        }
    }

    private List<MenuItemViewModel> children;

    public MenuItemViewModel()
    {
        children = new List<MenuItemViewModel>();
    }
}

视图(附加内容):

<Window x:Class="GUI.MainWindow"
    xmlns=""
    "
    "
    Title="HTX-Formler" Height="350" Width="525"
    WindowStartupLocation="CenterScreen">
<Window.Resources>
    <Style TargetType="{x:Type MenuItem}">
        <Setter Property="Header" Value="{Binding Path=Text}"/>
        <Setter Property="Command" Value="{Binding Path=Command}"/>
    </Style>
    <HierarchicalDataTemplate 
    DataType="{x:Type vm:MenuItemViewModel}"
    ItemsSource="{Binding Path=Children}">
    </HierarchicalDataTemplate>
</Window.Resources>

<DockPanel KeyboardNavigation.TabNavigation="None">
    <Menu DockPanel.Dock="Top" ItemsSource="{Binding Path=Children}" />
</DockPanel>

据我所知,绑定很好,但无论我做什么,我都无法让菜单显示任何东西。
我有一种感觉,因为我使用了错误的ItemsSource,所以我尝试了以下操作:

class MainWindowViewModel
{
    #region Fields

    ReadOnlyCollection<MenuItemViewModel> _menuItems;

    #endregion

    #region Menu

    public ReadOnlyCollection<MenuItemViewModel> Children
    {
        get
        {
            if (_menuItems == null)
            {
                List<MenuItemViewModel> menuItems = this.PopulateMenu();
                _menuItems = new ReadOnlyCollection<MenuItemViewModel>(menuItems);
            }
            return _menuItems;
        }
    }

    List<MenuItemViewModel> PopulateMenu()
    {
        return new List<MenuItemViewModel>
        {
            new MenuItemViewModel()
        };
    }

    #endregion
}

但无济于事。我意识到该集合与Children属性具有相同的名称,但更改了col的名称。没有效果。

摘要

以这种方式创建菜单栏的最佳方法是什么? 填充菜单集的最佳方法是什么?

大量的灵感来自以下来源:

是的,有些链接是针对SO的 不,我认为这不是一个重复的问题,因为我认为上述来源缺少我理解所固有的关键部分。如果这是某种重复,如果有人指出我错过的信息,我将不胜感激。

我为这个琐碎的事情道歉并了解我的大脑,答案可能非常简单,但我确实在我的智慧结束,所以任何和所有答案都将受到赞赏。

2 个答案:

答案 0 :(得分:0)

最简单的解决方案:在窗口的构造函数中设置DataContext

public class MainWindow: Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new MainWindowViewModel();
    }
}

答案 1 :(得分:0)

您可以在XAML中设置整个Window的DataContext,方法是将其放在Window定义中,例如:低于</Window.Resources>

<Window.DataContext>
    <vm:MenuItemViewModel/>
</Window.DataContext>