开发者

Bound WPF Menu using MVVM - Find the error

I'm trying to implement Menu in a Window using MVVM pattern. So I have created a MainWindow and bound it to MainWindowViewModel. MainWindowViewModel contains MainWindowMenuViewModel which is a VM specially designed for Menu. It's a hierarchical structure of MenuItemViewModels. All seems to be simple but I have a problem - when I run the application the menu is not rendered properly - it seems Header property is not set. The menu is there in top left corner but without any text displayed. I can click it and it opens but all MenuItems are blank. What's strange: bound ICommands work! But no Header is displayed. Here is my resources

<Style x:Key="MenuItemStyle" TargetType="{x:Type MenuItem}" >
    <Style.Setters>
        <Setter Property="Header" Value="{Binding Path=Title}" />
        <Setter Property="Command" Value="{Binding Path=Command}" />
    </Style.Setters>
</Style>

<HierarchicalDataTemplate
    x:Key="MenuDataTemplate"
    DataType="{x:Type vw:MenuItemViewModel}"
    ItemsSource="{Binding Path=SubMenuItems}"
    ItemContainerStyle="{StaticResource ResourceKey=MenuItemStyle}"
    >
</HierarchicalDataTemplate>

MainWindow.xaml contains menu:

<DockPanel>
    <Menu
        DockPanel.Dock="Top"
        ItemsSource="{Binding Path=Menu.MenuItems}"
        ItemTemplate="{StaticResource ResourceKey=MenuDataTemplate}"
        />
</DockPanel>

MenuItemView is:

using System.Collections.Generic;
using System开发者_如何学C.Windows.Input;

namespace WpfMvvmMenu.ViewModel
{
    public class MenuItemViewModel
    {
        public MenuItemViewModel(string title, ICommand command)
        {
            this.Title = title;
            this.Command = command;
            this.SubMenuItems = new List<MenuItemViewModel>();
        }

        public string Title { get; private set; }
        public ICommand Command { get; private set; }
        public IList<MenuItemViewModel> SubMenuItems { get; private set; }
    }
}

I saw all MVVM - Menu articles here, but they all say my DataTemplate is OK, so there must be something else.

Thank you.


I think that when you use HierarchicalDataTemplate, you set the Content of the templated MenuItem to the content of the template, even if you leave it empty. This code works:

<Style x:Key="MenuItemStyle" TargetType="{x:Type MenuItem}">
    <Style.Setters>
        <Setter Property="Command" Value="{Binding Path=Command}" />
    </Style.Setters>
</Style>

<HierarchicalDataTemplate
    x:Key="MenuDataTemplate"
    DataType="{x:Type vw:MenuItemViewModel}"
    ItemsSource="{Binding Path=SubMenuItems}"
    ItemContainerStyle="{StaticResource MenuItemStyle}"
    >
    <ContentPresenter Content="{Binding Title}" />
</HierarchicalDataTemplate>

On the other hand, you don't need the template at all. You can set ItemContainerStyle="{StaticResource MenuItemStyle}" directly on the menu while using the following style:

<Style x:Key="MenuItemStyle" TargetType="{x:Type MenuItem}">
    <Style.Setters>
        <Setter Property="Header" Value="{Binding Path=Title}" />
        <Setter Property="Command" Value="{Binding Path=Command}" />
        <Setter Property="ItemsSource" Value="{Binding SubMenuItems}" />
    </Style.Setters>
</Style>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜