views:

45

answers:

1

Is it possible in WPF to define some menu structure and than use it in multiple contexts? For example I'd like to use a set of menu items from resources in ContextMenu, Window's menu and ToolBar (ToolBar with icons only, without headers). So items order, commands, icons, separators must be defined just once.

I look for something like this:

Declaration in resources:

<MenuItem Command="MyCommands.CloneObject" 
          CommandParameter="{Binding SelectedObject}" Header="Clone">
    <MenuItem.Icon> 
        <Image Source="Images\Clone.png" Height="16" Width="16"></Image>
    </MenuItem.Icon>
</MenuItem>
<MenuItem Command="MyCommands.RemoveCommand" 
            CommandParameter="{Binding SelectedObject}" Header="Remove">
    <MenuItem.Icon>
        <Image Source="Images\Remove.png" Height="16" Width="16"></Image>
    </MenuItem.Icon>
</MenuItem>
<Separator/>
<MenuItem Command="MyCommands.CreateChild" 
            CommandParameter="{Binding SelectedObject}" Header="Create child">
    <MenuItem.Icon>
        <Image Source="Images\Child.png" Height="16" Width="16"></Image>
    </MenuItem.Icon>
</MenuItem>

Usage:

<ToolBar MenuItems(?)="{Reference to set of items}" ShowText(?)="false" />

and

<ContextMenu MenuItems(?)="{Reference to set of items}" />
A: 

You can do like this - make a user control and reuse that - the other will not work as UIElements only can one parent:

CustomMenu.xaml

<MenuItem x:Class="MyApplication.CustomMenu"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
    <MenuItem Command="MyCommands.CloneObject" 
          CommandParameter="{Binding SelectedObject}" Header="Clone">
        <MenuItem.Icon>
            <Image Source="Images\Clone.png" Height="16" Width="16"></Image>
        </MenuItem.Icon>
    </MenuItem>
    <MenuItem Command="MyCommands.RemoveCommand" 
            CommandParameter="{Binding SelectedObject}" Header="Remove">
        <MenuItem.Icon>
            <Image Source="Images\Remove.png" Height="16" Width="16"></Image>
        </MenuItem.Icon>
    </MenuItem>
    <Separator/>
    <MenuItem Command="MyCommands.CreateChild" 
            CommandParameter="{Binding SelectedObject}" Header="Create child">
        <MenuItem.Icon>
            <Image Source="Images\Child.png" Height="16" Width="16"></Image>
        </MenuItem.Icon>
    </MenuItem>
</MenuItem>

Code-behind CustomMenu.xaml.cs:

public partial class CustomMenu
{
    public CustomMenu()
    {
        InitializeComponent();
    }
}

And then use it in xaml like this:

<ToolBar>
    <local:CustomMenu/>
</ToolBar>
<ContextMenu>
    <local:CustomMenu/>
</ContextMenu>

Hope this helps.

Goblin
This is a good way to do it. By the way, what you wrote here is actually a "user control" which is slightly different than a "custom control". A custom control has no XAML file and no InitializeComponent call. Instead it sets its DefaultStyleKey and has a style defined in Themes/Generic.xaml or one of its merged dictionaries. A user control, which is what you have here, does not have the ability to have content added when it is used. A custom control does. A custom control is also more powerful in several ways. Just FYI. Your answer is a good one.
Ray Burns
You are of course right. I was being sloppy :-) I've edited my reply to reflect this.
Goblin