sth_Weird
sth_Weird

Reputation: 660

WPF Merge ContextMenues in XAML

is it possible to merge two ContextMenues in XAML?

I created two ContextMenues as resources. I use them in a couple of DataTemplates and it works fine. However, for some DataTemplates, I would like to merge the two ContextMenues. Unfortunately, this does not seem to work. Here's a bit of the code from one of these ContextMenues, the other ones are defined the same:

<ContextMenu x:Key="CtxIEditableViewModel" DataContext="{Binding PlacementTarget,RelativeSource={RelativeSource Self}}">
    <MenuItem Header="Edit" Command="{Binding Path=DataContext.EditCommand}" CommandParameter="{Binding }">
        <MenuItem.Icon>
            <Image Source="{StaticResource IcoEdit}"  Width="16" Height="16"></Image>
        </MenuItem.Icon>
    </MenuItem>
    ...

Using one of those ContextMenues works fine:

<StackPanel Orientation="Horizontal" ContextMenu="{StaticResource CtxIEditableViewModel}">

But how to merge two? This does not work

<StackPanel Orientation="Horizontal">
        <ContextMenu>
            <ContextMenu.ItemsSource>
                <CompositeCollection>
                    <StaticResource ResourceKey="CtxIEditableViewModel" />
                    <StaticResource ResourceKey="CtxRootViewModel" />
                </CompositeCollection>
            </ContextMenu.ItemsSource>

And this does not work either:

<StackPanel Orientation="Horizontal">
        <ContextMenu>
            <StaticResource ResourceKey="CtxIEditableViewModel" />
            <StaticResource ResourceKey="CtxRootViewModel" />
        </ContextMenu>

When I run the programm an exception is thrown saying that the context menu may not contain a logical or visual parent. Since it works fine if I only use one ContextMenu, I do not understand the exception message.

How can I merge those two ContextMenues in XAML (or is it not possible at all)?

Upvotes: 5

Views: 2251

Answers (1)

SamTh3D3v
SamTh3D3v

Reputation: 9944

here one way to do it using CompositeCollection

<Window.Resources>
    <ResourceDictionary>
        <x:Array Type="{x:Type sys:Object}" x:Key="CtxIEditableViewModel" x:Shared="false">
            <MenuItem Header="Edit1"/>
            <MenuItem Header="Edit2"/>
        </x:Array>
        <x:Array Type="{x:Type sys:Object}" x:Key="CtxRootViewModel" x:Shared="false">
            <MenuItem Header="Root1" />
            <MenuItem Header="Root2"/>
        </x:Array>              
    </ResourceDictionary>
</Window.Resources>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Border Grid.Row="0" Background="LightBlue">
        <Border.ContextMenu>
            <ContextMenu>
                <ContextMenu.ItemsSource>
                    <CompositeCollection>
                        <CollectionContainer Collection="{StaticResource CtxIEditableViewModel}" />                            
                    </CompositeCollection>
                </ContextMenu.ItemsSource>
            </ContextMenu>
        </Border.ContextMenu>
    </Border>
    <Border Grid.Row="1" Background="LightGreen">
        <Border.ContextMenu>
            <ContextMenu>
                <ContextMenu.ItemsSource>
                    <CompositeCollection>                            
                        <CollectionContainer Collection="{StaticResource CtxRootViewModel}" />
                    </CompositeCollection>
                </ContextMenu.ItemsSource>
            </ContextMenu>
        </Border.ContextMenu>
    </Border>
    <Border Grid.Row="2" Background="Khaki">
        <Border.ContextMenu>
            <ContextMenu>
                <ContextMenu.ItemsSource>
                    <CompositeCollection>                            
                        <CollectionContainer Collection="{StaticResource CtxIEditableViewModel}" />
                        <CollectionContainer Collection="{StaticResource CtxRootViewModel}" />
                    </CompositeCollection>
                </ContextMenu.ItemsSource>
            </ContextMenu>

        </Border.ContextMenu>
    </Border>
</Grid>

PS: x:Shared="false" is important because without it unique instances will be re-used several context menus, and they fail to work that way. There would be missing menu items with or without reserved space for them.

Upvotes: 10

Related Questions