Dynamically linking ViewModel commands in a Window MenuItem

Working with a WPF application using the MVVM framework.

My window displays the menu and the current ViewModel. In one of the MenuItems, I want to list some of the commands found in the current ViewModel. The commands listed in the menu will vary depending on the ViewModel.

It worked out just fine for me, but the style was messed up - the menu command elements are inside another menu window or something like that. I will attach a screenshot.

I wrapped the ViewModel ICommand objects (RelayCommands, in this case) in the CommandViewModel that displays the Command and Display line that I want in the menu. These CommandViewModels are listed: CurrentWorkspace.AdditionalOptionsCommands .

Here is the XAML for the menu. As I said, it works, it shows the correct elements and the commands are executed. The display is simply incorrect - can someone tell me why and how to fix it? See 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:

Current appearance

Desired appearance:

Desired appearance

+4
source share
1 answer

This is due to the fact that when specifying menu items through ItemsSource each item is automatically included in the MenuItem object. Thus, the content defined in the DataTemplate ( MenuItem ) is transferred to another MenuItem .

Instead of defining a DataTemplate you need to define a style for the MenuItem where you set the bindings on the properties of the view model and use this style as ItemContainerStyle in 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 a detailed explanation of how item containers work with ItemsControl controls.

+7
source

All Articles