How to correctly bind a ViewModel (which Include Separators) to WPF's Menu?

Solved my own question

After spending several hours searching the web, I found lots of examples that work against the WPF's natural intentions but none that worked with it.

Here's how to work with the Menu control and not against it...

A little Background

WPF's Menu control will normally auto create MenuItem objects for you when it is binded to a POCO collection, using the ItemsSource property.

However, this default behavior can be overridden! Here's how...

The Solution

First, you must create a class that derives from ItemContainerTemplateSelector. Or use the simple class I've created:

public class MenuItemContainerTemplateSelector : ItemContainerTemplateSelector
    public override DataTemplate SelectTemplate(object item, ItemsControl parentItemsControl)
        var key = new DataTemplateKey(item.GetType());
        return (DataTemplate) parentItemsControl.FindResource(key);

Second, you must add a reference to the MenuItemContainerTemplateSelector class to your Windows resources object, like so:

    <Selectors:MenuItemContainerTemplateSelector x:Key="_menuItemContainerTemplateSelector" />

Third, you must set two properties (UsesItemContainerTemplate, and ItemContainerTemplateSelector) on both the Menu and the MenuItem (which is defined in the HierarchicalDataTemplate).

Like so:

    <HierarchicalDataTemplate DataType="{x:Type ViewModel:MenuItemViewModel}"
        ItemsSource="{Binding Children}">
        <MenuItem Header="{Binding Header}"
                  Command="{Binding Command}"
                  UsesItemContainerTemplate ="true"
                  "{StaticResource _menuItemContainerTemplateSelector}"/>

    <Menu DockPanel.Dock="Top"
          ItemsSource="{Binding MenuItems}"
          "{StaticResource _menuItemContainerTemplateSelector}">

Why it Works

For optimization purposes, the Menu uses the UsesItemContainerTemplate flag (which has a default value of false) to skip the DataTemplate lookup and just returns a normal MenuItem object. Therefore, we needed to set this value to true and then our ItemContainerTemplateSelector works as expected.

Happy Coding!

A solution without the TemplateSelector:

provide ItemContainerTemplates instead of the DataTemplates :

<ContextMenu ItemsSource="{Binding Path=MenuItems}" UsesItemContainerTemplate="True">
                  <ItemContainerTemplate DataType="{x:Type ViewModel:MenuItemViewModel }">
                    <MenuItem Header="{Binding Path=Header}" Command="{Binding Path=Command}" UsesItemContainerTemplate="True">
                        <Image Source="{Binding Path=ImageSource}"/>
                  <ItemContainerTemplate DataType="{x:Type ViewModel:SeparatorViewModel}">
                    <Separator >
                        <Style TargetType="{x:Type Separator}" BasedOn="{StaticResource ResourceKey={x:Static MenuItem.SeparatorStyleKey}}"/>


  • I haven't tried Children
  • the separator styled wrong: I had to manually re-apply the style