I have TreeView which contains different item types. Item Styles are defined over a custom ItemContainerStyleSelector property.
My styles are all sharing a base style and only item specific stuff is defined in each style. It looks like this:
<Style x:Key="BaseStyle" TargetType="{x:Type TreeViewItem}">
...
</Style>
<Style x:Key ="SomeSpecificStyle" TargetType="{x:Type TreeViewItem}" BasedOn="{StaticResource BaseStyle}">
<Setter Property="ContextMenu" Value="{StaticResource NodeContextMenu}"/>
...
</Style>
<Style x:Key ="SomeSpecificStyle" TargetType="{x:Type TreeViewItem}" BasedOn="{StaticResource BaseStyle}">
<Setter Property="ContextMenu" Value="{StaticResource AnotherNodeContextMenu}"/>
...
</Style>
The context menu is defined like this
<ContextMenu x:Key="NodeContextMenu">
<MenuItem Header="Select Views" Command="{Binding Path=OpenViewsCommand}" />
...other specific entries
<MenuItem Header="Remove" Command="{Binding Path=DocumentRemoveCommand}" />
...other entries common for all menus
</ContextMenu>
Another context menu also should contain those common items like remove. These need to be replicated by copy paste every time the command properties, etc are changing. A hell for maintainability. Is there a way to define a context menu which contains the common items, and then “derive” specific context menus?
Edit: I found a solution with the hints from this thread:
I define a Collection with the common items, and use a composite collection when defining a menu to include both new items and the common items collection
<CompositeCollection x:Key="CommonItems">
<MenuItem Header="Remove" Command="{Binding Path=DocumentRemoveCommand}">
....Other common stuff
</CompositeCollection>
<ContextMenu x:Key="NodeContextMenu">
<ContextMenu.ItemsSource>
<CompositeCollection>
<MenuItem Header="Select Views" Command="{Binding Path=OpenViewsCommand}" />
<CollectionContainer Collection="{StaticResource CommonItems}" />
</CompositeCollection>
</ContextMenu.ItemsSource>
</ContextMenu>
You can declare the items as resource and reference them:
(The
x:Sharedis important)Another possibility would be to generate
MenuItemsvia a object model approach, you just bind theItemsSourceto some list of objects which model the functionality of aMenuItem(i.e. properties for child items, header and command), then you can create oneRemovemodel which can be part of multiple lists.