How to add menu items to menu control (not contextmenu) in WPF from a database table with Bindings and Observable collections?. I have this menu:
<Menu HorizontalAlignment="Left" Height="27" VerticalAlignment="Top" Width="649">
<MenuItem Header="_File">
<MenuItem Header="_Exit" Command="{Binding ExitCommand}"/>
</MenuItem>
<MenuItem Header="_MyMenu">
<MenuItem Header="_SubMenu1" Command="{Binding SubMenu1Command}" />
<MenuItem Header="_SubMenu2" Command="{Binding SubMenu2Command}" />
</MenuItem>
</Menu>
The "SubMenu1" and "_SuMenu2" are values from the database table:
codSubMenu | SubMenuColum | CommandColumn
1__________|SubMenu1_____|SubMenu1Command 2__________|SubMenu2_____|_SubMenu2Command
I need something this:
<Menu HorizontalAlignment="Left" Height="27" VerticalAlignment="Top" Width="649"
ItemsSource="{Binding ObservableCollectionMenu}">
<MenuItem Header="_File">
<MenuItem Header="_Exit" Command="{Binding ExitCommand}"/>
</MenuItem>
<MenuItem Header="_MyMenu">
<MenuItem Header="{Binding ObservableCollectionMenu.SubMenuColumn}" Command="{Binding ObservableCollectionMenu.CommandColumn}" />
</MenuItem>
</Menu>
When I run the app the menu must show this when I press the options File and MyMenu:
File | MyMenu
Exit | SubMenu1
___| SubMenu2
Use the ItemsSource
property of the Menu and the MenuItems (in a style) to bind your collections:
<Menu ItemsSource="{Binding YourCollection}" />
and
<Style TargetType="MenuItem">
<Setter Property="Header" Value="{Binding Path=Name}" />
<Setter Property="ItemsSource" Value="{Binding Path=Children}" />
</Style>
Edit: For command binding do the following:
Add a setter like this to the template of the MenuItem:
<Setter Property="Command" Value="{Binding Path=Command}" />
Use this structure for a MenuItem
view model:
public class BindableMenuItem
{
public string Name { get; set; }
public BindableMenuItem[] Children { get; set; }
public ICommand Command { get; set; }
}
Add the root items to a collection of BindableMenuItems
and bind this collection to the menu.
This is how I solved it,
I created a MenuItem class (notice that it has a list of Items so you can build sub-menus):
public class MenuItem : ModelBase<MenuItem>
{
private List<MenuItem> _Items;
public MenuItem(string header, ICommand command)
{
Header = header;
Command = command;
}
public MenuItem()
{
}
public string Header { get; set; }
public List<IMenuItem> Items
{
get { return _Items ?? (_Items = new List<IMenuItem>()); }
set { _Items = value; }
}
public ICommand Command { get; set; }
public string CommandName { get; set; }
public object Icon { get; set; }
public bool IsCheckable { get; set; }
private bool _IsChecked;
public bool IsChecked
{
get { return _IsChecked; }
set
{
_IsChecked = value;
NotifyPropertyChanged(m=>m.IsChecked);
}
}
public bool Visible { get; set; }
public bool IsSeparator { get; set; }
public string InputGestureText { get; set; }
public string ToolTip { get; set; }
public int MenuHierarchyID { get; set; }
public int ParentMenuHierarchyID { get; set; }
public string IconPath { get; set; }
public bool IsAdminOnly { get; set; }
public object Context { get; set; }
public IMenuItem Parent { get; set; }
public int int_Sequence { get; set; }
public int int_KeyIndex { get; set; }
}
And a View:
<Menu DockPanel.Dock="Top" ItemsSource="{Binding Path=MainMenu}">
<Menu.ItemContainerStyle>
<Style>
<Setter Property="MenuItem.Header" Value="{Binding Path=Header}" />
<Setter Property="MenuItem.ItemsSource" Value="{Binding Path=Items}" />
<Setter Property="MenuItem.Icon" Value="{Binding Path=Icon}" />
<Setter Property="MenuItem.IsCheckable" Value="{Binding Path=IsCheckable}" />
<Setter Property="MenuItem.IsChecked" Value="{Binding Path=IsChecked,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
<Setter Property="MenuItem.Command" Value="{Binding Path=Command}" />
<!--<Setter Property="MenuItem.CommandParameter" Value="{Binding Path=IsChecked}"/>-->
<Setter Property="MenuItem.CommandParameter" Value="{Binding Path=.}"/>
<Setter Property="MenuItem.InputGestureText" Value="{Binding Path=InputGestureText}"/>
<Setter Property="MenuItem.ToolTip" Value="{Binding Path=ToolTip}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsSeparator}" Value="true">
<Setter Property="MenuItem.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Separator Style="{DynamicResource {x:Static MenuItem.SeparatorStyleKey}}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Menu.ItemContainerStyle>
</Menu>
Where MainMenu
is an ObservableCollection
property in my main ViewModel, which you can populate from your database.
public ObservableCollection<MenuItem> MainMenu
{
get { return _MainMenu; }
set
{
_MainMenu = value;
NotifyPropertyChanged(x => x.MainMenu);
}
}
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