I am having trouble write the xaml representation to allow to bind to my background ViewModel for cascading menus
here's the VM:
public class MenuNode
{
public string Header {get;}
public List<MenuNode> Items {get;}
}
the xaml i have is this:
<ContextMenu ItemsSource="{Binding Choices}" >
<ContextMenu.Resources>
<DataTemplate DataType="{x:Type vmi:MenuNode}">
<MenuItem Header="{Binding Header}" ItemsSource="{Binding Items}"/>
</DataTemplate>
</ContextMenu.Resources>
</ContextMenu>
When the menu pops up I get the first-level entries with an arrow(indicating that there should be a sub-menu) but when i hover over the menu it doesn't show the sub-menu items.
Any ideas?
OK, here's the issue:
For some reason, the MenuItems
that were generated by your DataTemplate
are getting wrapped inside of another MenuItem
(the result was nested MenuItems
). The sub items were not being opened because the outer MenuItem
had no children.
The solution is to use a HierarchicalDataTemplate
instead:
<ContextMenu ItemsSource="{Binding Choices}" >
<ContextMenu.Resources>
<HierarchicalDataTemplate DataType="{x:Type vmi:MenuNode}" ItemsSource="{Binding Items}">
<TextBlock Text="{Binding Header}"/>
</HierarchicalDataTemplate>
</ContextMenu.Resources>
</ContextMenu>
my take on MenuItems and MVVM (it was not easy to put Icons in there)
public class MenuItemVM
{
public string Text { get; set; }
public List<MenuItemVM> Children { get; set; }
public ICommand Command { get; set; }
public ImageSource Icon { get; set; }
}
public IList<MenuItemVM> AddContextMenu { get; set; }
View:
<Image x:Key="MenuItemIcon"
x:Shared="false"
Source="{Binding Icon}"
Height="16px"
Width="16px"/>
<Style x:Key="ContextMenuItemStyle" TargetType="{x:Type MenuItem}">
<Setter Property="MenuItem.Icon" Value="{StaticResource MenuItemIcon}"/>
<Setter Property="MenuItem.Command" Value="{Binding Command}" />
<Style.Triggers>
<!-- insert a null in ItemsSource if you want a separator -->
<DataTrigger Binding="{Binding}" Value="{x:Null}">
<Setter Property="Template" >
<Setter.Value>
<ControlTemplate>
<Separator Style="{StaticResource {x:Static MenuItem.SeparatorStyleKey}}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
Add the contextmenu to your UI
<ContextMenu ItemContainerStyle="{StaticResource ContextMenuItemStyle}"
ItemsSource="{Binding AddContextMenu}">
<ContextMenu.Resources>
<HierarchicalDataTemplate DataType="{x:Type vmp:MenuItemVM}"
ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Text}"/>
</HierarchicalDataTemplate>
</ContextMenu.Resources>
</ContextMenu>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With