WPF FAQ - Context Menu

How do I bind the ContextMenu to a list of commands?

It’s possible that you have a list of commands that you simply want to bind to a context menu. You can do so as follows.

For example, if you have list of custom commands, each of this type:

[C#]
public class MyCommand
{
public Name{get; set;}
public Command{get; set;}
}

Then you can bind a list containing the above items to a ContextMenu as follows:

<ContextMenu>
  <ContextMenu.ItemContainerStyle>
    <Style TargetType='{x:Type MenuItem}'>
      <Setter Property='Command' Value='{Binding ContextMenuItemCommand}'/>
    </Style>
  </ContextMenu.ItemContainerStyle>
</ContextMenu>

<ContextMenu ItemsSource={StaticResource myList}></ContextMenu>
Permalink
How do I listen to click events on all the MenuItems through the parent ContextMenu?

Instead of setting up event handlers on all the MenuItems you can listen to those events as they bubble up to the context menu as follows:

[XAML]

            MenuItem1
            MenuItem2
            MenuItem3
            MenuItem4

Or you can setup the same thing in code as follows:

[C#]
menuItem1.AddHandler(MenuItem.ClickEvent, new RoutedEventHandler(MnItem_Click));

The event handler would then be something like:

private void MnItem_Click(object sender, RoutedEventArgs e)
{
	MenuItem item = e.Source as MenuItem;
            
	....
}
Permalink
How can I enable a Context Menu on a disabled Control ?

This example uses the ContextMenuService.ShowOnDisabled property to show the context menu for a disabled button.

[XAML]

<Button Height='30' Content='Disabled Button' IsEnabled='False' 
     ContextMenuService.ShowOnDisabled='True'>
  <Button.ContextMenu>
    <ContextMenu>
      <MenuItem Header='Item 1'/>
      <MenuItem Header='Item 2'/>
      <MenuItem Header='Item 3'/>
    </ContextMenu>
  </Button.ContextMenu>
</Button>
Permalink
How do I make the Context Menu to close after a set time interval?

To automatically close the context menu after a set time interval, you can use a Timer and send an Esc keystroke after the desired time interval as shown.

[C#]

private void timer1_Tick(object sender, System.EventArgs e)
{
SendKeys.Send('{ESC}');
timer1.Stop();
}

private void contextMenu1_Popup(object sender, System.EventArgs e)
{
//set interval to 5 seconds
timer1.Interval = 5000;
timer1.Start();
}
Permalink