Working on a WPF application using the MVVM structure.
My Window displays a menu and the current ViewModel. On one of the Menu's MenuItems, I want to list some Commands found in the current ViewModel. The commands listed in the Menu will change depending on the ViewModel.
I got this to work just fine, but the style is messed up - the Command MenuItems are inside another menu box or something. I'll attach a screenshot.
I wrapped the ViewModel's ICommand objects (RelayCommands, in this instance) in CommandViewModel, which expose the Command and the Display string I want on the menu. These CommandViewModels are in a list: CurrentWorkspace.AdditionalOptionsCommands
.
Here is the XAML for the Menu. Like I said, it works, it shows the right items a开发者_如何学编程nd the commands are executed. The display is just incorrect - can anybody tell me why and how to fix it? See the screenshot.
<Menu>
<MenuItem Header="_Additional Options..." ItemsSource="{Binding Path=CurrentWorkspace.AdditionalOptionsCommands}">
<MenuItem.ItemTemplate>
<DataTemplate DataType="{x:Type vm:CommandViewModel}">
<MenuItem Header="{Binding Path=DisplayText}" Command="{Binding Path=Command}"/>
</DataTemplate>
</MenuItem.ItemTemplate>
</MenuItem>
<MenuItem Header="_Testing">
<MenuItem Header="This looks right" />
<MenuItem Header="This looks right" />
</MenuItem>
</Menu>
Current Appearance:
Desired Appearance:
This is because when you specify menu items via ItemsSource
each item gets automatically wrapped into a MenuItem
object. This way the content defined in the DataTemplate
(MenuItem
element) gets wrapped into one more MenuItem
.
What you need to do instead of defining a DataTemplate
is to define a style for the MenuItem
where you setup bindings to the view model's properties and use this style as ItemContainerStyle
on the parent MenuItem
:
<Window.Resources>
<Style x:Key="CommandMenuItemStyle"
TargetType="{x:Type MenuItem}">
<Setter Property="Header"
Value="{Binding Path=DisplayText}"/>
<Setter Property="Command"
Value="{Binding Path=Command}"/>
</Style>
</Window.Resources>
...
<Menu>
<MenuItem Header="_Additional Options..."
ItemsSource="{Binding Path=CurrentWorkspace.AdditionalOptionsCommands}"
ItemContainerStyle="{StaticResource CommandMenuItemStyle}"/>
<MenuItem Header="_Testing">
<MenuItem Header="This looks right" />
<MenuItem Header="This looks right" />
</MenuItem>
</Menu>
See http://drwpf.com/blog/2008/03/25/itemscontrol-i-is-for-item-container/ for an in-depth explanation on how item containers work with ItemsControl
controls.
精彩评论