Question

In my WPF app, when a ContextMenu is opening, I want to tweak its menu items depending on whether or not the Alt key is pressed.

I've got the logic working. XAML:

<my:Control ContextMenuOpening="MyContextMenu_Opening" />

Code:

private void MyContextMenu_Opening(object sender, RoutedEventArgs args) {
  bool isAltDown = Keyboard.IsKeyDown(Key.LeftAlt);
  /* tweak menu items here */
}

My problem is that when the Alt key is pressed, the context menu opens and then immediately closes (I can see in the flash of it being open that my logic is at least working).

I wonder is this a WPF 'feature' in general because if I even hold Alt while right clicking on a TextField, the same thing happens - the built-in Cut/Copy/Paste menu flashes open then immediately closes.

One hunch is that it has something to do with Alt activating the application menu bar. But an application menu bar does not apply to my situation, so if the solution involves messing with that, it will still work for me.

Was it helpful?

Solution

This is a built-In behavior in the MenuBase class:

        protected override void OnKeyDown(KeyEventArgs e)
        {
            .....
            if (((e.SystemKey == Key.LeftAlt) || (e.SystemKey == Key.RightAlt)) || (e.SystemKey == Key.F10))
            {
                this.KeyboardLeaveMenuMode();
                e.Handled = true;
            }
        }

Why not use another Modifier Key ??

OTHER TIPS

this is a built in behavior from MSDN MenuBase.OnKeyDown

    If the user presses ESC, ALT+ALT, or ALT+F10, 
    this implementation marks the KeyDown event as handled 
    by setting the Handled property of the event data to true.

You can still use the Alt key, just override the base class behavior:

public class AltProofContextMenu : ContextMenu
{
    protected override void OnKeyDown(KeyEventArgs e)
    {
        if(!(e.SystemKey == Key.LeftAlt || e.SystemKey == Key.RightAlt))
            base.OnKeyDown(e);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top