WPF Menu control is represented by the Menu class in C#. This menus tutorial and menus code examples explain how to use menus in WPF using C#. In WPF, the Menu and the MenuItem classes represent a menu and a menu item respectively. A Menu is a collection of menu items with a command associated with each menu item.
WPF binding offers four types of Binding. Remember, Binding runs on UI thread unless otherwise you specify it to run otherwise. OneWay: The target property will listen to the source property being changed and will update itself.
The <Menu> and <MenuItem> XAML elements are used to create menus in XAML.
For me, it worked with this simple template:
<Menu.ItemContainerStyle>
    <Style TargetType="{x:Type MenuItem}">
        <Setter Property="Command" Value="{Binding Command}" />
    </Style>
</Menu.ItemContainerStyle>
<Menu.ItemTemplate>
    <HierarchicalDataTemplate DataType="{x:Type local:MenuItemViewModel}" ItemsSource="{Binding Path=MenuItems}">
        <TextBlock Text="{Binding Header}"/>
    </HierarchicalDataTemplate>
</Menu.ItemTemplate>
Here is the complete example:
MainWindow.xaml:
<Window x:Class="WpfApplication14.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication14"
        Title="MainWindow" Height="350" Width="525">
    <DockPanel>
        <Menu DockPanel.Dock="Top" ItemsSource="{Binding MenuItems}">
            <Menu.ItemContainerStyle>
                <Style TargetType="{x:Type MenuItem}">
                    <Setter Property="Command" Value="{Binding Command}" />
                </Style>
            </Menu.ItemContainerStyle>
            <Menu.ItemTemplate>
                <HierarchicalDataTemplate DataType="{x:Type local:MenuItemViewModel}" ItemsSource="{Binding Path=MenuItems}">
                    <TextBlock Text="{Binding Header}"/>
                </HierarchicalDataTemplate>
            </Menu.ItemTemplate>
        </Menu>
        <Grid>
        </Grid>
    </DockPanel>
</Window>
MainWindow.xaml.cs:
using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Input;
namespace WpfApplication14
{
    public partial class MainWindow : Window
    {
        public ObservableCollection<MenuItemViewModel> MenuItems { get; set; }
        public MainWindow()
        {
            InitializeComponent();
            MenuItems = new ObservableCollection<MenuItemViewModel>
            {
                new MenuItemViewModel { Header = "Alpha" },
                new MenuItemViewModel { Header = "Beta",
                    MenuItems = new ObservableCollection<MenuItemViewModel>
                        {
                            new MenuItemViewModel { Header = "Beta1" },
                            new MenuItemViewModel { Header = "Beta2",
                                MenuItems = new ObservableCollection<MenuItemViewModel>
                                {
                                    new MenuItemViewModel { Header = "Beta1a" },
                                    new MenuItemViewModel { Header = "Beta1b" },
                                    new MenuItemViewModel { Header = "Beta1c" }
                                }
                            },
                            new MenuItemViewModel { Header = "Beta3" }
                        }
                },
                new MenuItemViewModel { Header = "Gamma" }
            };
            DataContext = this;
        }
    }
    public class MenuItemViewModel
    {
        private readonly ICommand _command;
        public MenuItemViewModel()
        {
            _command = new CommandViewModel(Execute);
        }
        public string Header { get; set; }
        public ObservableCollection<MenuItemViewModel> MenuItems { get; set; }
        public ICommand Command
        {
            get
            {
                return _command;
            }
        }
        private void Execute()
        {
            // (NOTE: In a view model, you normally should not use MessageBox.Show()).
            MessageBox.Show("Clicked at " + Header);
        }
    }
    public class CommandViewModel : ICommand
    {
        private readonly Action _action;
        public CommandViewModel(Action action)
        {
            _action = action;
        }
        public void Execute(object o)
        {
            _action();
        }
        public bool CanExecute(object o)
        {
            return true;
        }
        public event EventHandler CanExecuteChanged
        {
            add { }
            remove { }
        }
    }
}
The resulting window looks like this:

that is very easy,you can use this code for your nested menu
ViewModel: TopMenuViewModel.cs
public partial class TopMenuViewModel 
{
    public TopMenuViewModel()
    {
        TopMenuItems = new ObservableCollection<MenuItem>
        {
            new MenuItem
            {
                Title = "File",
                PageName =typeof(OfficeListView).FullName,
                ChildMenuItems= {
                    new MenuItem
                    {
                        Title = "New"
                    },
                     new MenuItem
                    {
                        Title = "Open"
                    },
                     new MenuItem
                    {
                        Title = "Save"
                    }
                }
            },
            new MenuItem
            {
                Title = "Edit"
            },
            new MenuItem
            {
                Title = "Search"
            }
        };
    }
View: TopMenuView.xaml
<Menu IsMainMenu="True" ItemsSource="{Binding TopMenuItems}">
            <Menu.ItemContainerStyle>
                <Style TargetType="{x:Type MenuItem}">
                    <Setter Property="Header" Value="{Binding Title}"/>
                    <Setter Property="ItemsSource" Value="{Binding Path=ChildMenuItems}"/>
                </Style>
            </Menu.ItemContainerStyle>
</Menu>   
    If like me you are keen to keep UI constructs in the XAML code, after some difficulty, I have worked a nice way of binding custom-typed collections to create menu items.
In XAML:
<Menu DockPanel.Dock="Top">
    <MenuItem Header="SomeHeaderName" ItemsSource="{Binding Path=MyCollection}">
        <MenuItem.ItemsContainerStyle>
            <Setter Property="Header" Value="{Binding Path=SomeRelevantTextProperty}"/>
            <EventSetter Event="Click" Handler="SomeMenuItemClickEventHandler"/>
        </MenuItem.ItemsContainerStyle>
    </MenuItem>
</Menu>
In code-behind:
ObservableCollection<MyClass> MyCollection;
private void SomeMenuItemClickEventHandler(object sender, RoutedEventArgs e)
{
    MenuItem menuItem = sender as MenuItem;
    MyClass myClass = menuItem.DataContext as MyClass;
    // do something useful!
}
public class MyClass
{
    public string SomeRelevantTextProperty { get; }
}
    
                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