How do I dynamically bind and statically add MenuItems?
You can use a CompositeCollection
to do this, you can combine different Collections and add static items in the xaml.
Example:
Xaml:
<Window x:Class="WpfApplication8.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="233" Width="143" Name="UI">
<Window.Resources>
<CollectionViewSource Source="{Binding ElementName=UI, Path=Windows}" x:Key="YourMenuItems"/>
</Window.Resources>
<Grid DataContext="{Binding ElementName=UI}">
<Menu Height="24" VerticalAlignment="Top">
<MenuItem Header="_View" >
<MenuItem Header="Windows">
<MenuItem.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{Binding Source={StaticResource YourMenuItems}}" />
<MenuItem Header="Menu Item 1" />
<MenuItem Header="Menu Item 2" />
<MenuItem Header="Menu Item 3" />
</CompositeCollection>
</MenuItem.ItemsSource>
<MenuItem.ItemContainerStyle>
<Style>
<Setter Property="MenuItem.Header" Value="{Binding Title}"/>
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
</MenuItem>
</Menu>
</Grid>
</Window>
Code
public partial class MainWindow : Window
{
private ObservableCollection<MyObject> _windows = new ObservableCollection<MyObject>();
public MainWindow()
{
InitializeComponent();
Windows.Add(new MyObject { Title = "Collection Item 1" });
Windows.Add(new MyObject { Title = "Collection Item 2" });
}
public ObservableCollection<MyObject> Windows
{
get { return _windows; }
set { _windows = value; }
}
}
public class MyObject
{
public string Title { get; set; }
}
Result:
Related videos on Youtube
webe0316
Merge with http://stackoverflow.com/users/598859/webe0316
Updated on June 19, 2022Comments
-
webe0316 almost 2 years
I'm binding the ItemsSource of my MenuItem to an ObservableCollection in my ViewModel. Here is my xaml:
<MenuItem Header="_View" ItemsSource="{Binding Windows}"> <MenuItem.ItemContainerStyle> <Style> <Setter Property="MenuItem.Header" Value="{Binding Title}" /> </Style> </MenuItem.ItemContainerStyle> </MenuItem>
This part works great, but now I also want to add some static MenuItems to the same View MenuItem, separated with a separator. Something like this, even though I know this won't work because I can't set the items twice.
<MenuItem Header="_View" ItemsSource="{Binding Windows}"> <MenuItem.ItemContainerStyle> <Style> <Setter Property="MenuItem.Header" Value="{Binding Title}" /> </Style> </MenuItem.ItemContainerStyle> <Separator /> <MenuItem Header="item 1" /> <MenuItem Header="item 2" /> </MenuItem>
For now I have created a work around by adding another level to the MenuItem like this:
<MenuItem Header="_View"> <MenuItem Header="Windows" ItemsSource="{Binding Windows}"> <MenuItem.ItemContainerStyle> <Style> <Setter Property="MenuItem.Header" Value="{Binding Title}" /> </Style> </MenuItem.ItemContainerStyle> </MenuItem> <MenuItem Header="Load Layout" /> <MenuItem Header="Save Layout" /> </MenuItem>
This works fine, but I'd rather not have a sub menu if at all possible. Oh, and I'd also prefer to do this in xaml instead of code behind. Any ideas?
-
Federico Berasategui over 11 yearsMaybe you can use CompositeCollection to "unify" your collection from the VM with your XAML defined collection.
-
-
Pyritie over 7 yearsWhat is the
{Binding ElementName=UI}
stuff for? -
JobaDiniz over 7 yearswhat if I'm data binding
Menu
ItemsSource (not one of its MenuItems)? I couldn't get theItemContainerStyle
to work, because I setMenu.ItemContainerStyle
and that's wrong...