How to prevent Enter press from closing menu

2019-07-09 04:13发布

问题:

I'm embedding a Colour Picker into a Context Menu using the Windows.Forms.ToolStripControlHost class. The picker displays fine and handles all mouse events properly:

The problem arises when one of the channel sliders is double clicked. This causes the control to add a Windows.Forms.TextBox into the parent control with the same dimensions as the slider so users can enter numeric values. When Enter is pressed while the TextBox has focus, it should assign the value and hide the textbox (which it does), but it also closes the entire menu structure. So, how do I keep the menu alive?

There's an awful lot of code involved but I'll post it if needed.

回答1:

Somehow, you'll need to eat the Enter key presses before they reach your context menu. Obviously, it's default behavior is to "select" the currently highlighted item when the user presses Enter, just like every other menu control known to man.

You would do that by subclassing the ContextMenuStrip control (if you're not doing so already), and overriding its ProcessCmdKey method. Watch for a keyData value corresponding to Keys.Enter, and when you detect that value, return True to indicate that the character was already processed by the control and prevent it from being passed on for any further processing. Everything else, of course, you'll let the base class process so the behavior of other keys (such as the arrow keys) is unchanged.

For example (I just tested this and it works fine):

public class CrazyContextMenuStrip : ContextMenuStrip
{
    protected override bool ProcessCmdKey(ref Message m, Keys keyData)
    {
        if (keyData == Keys.Enter)
        {
            // Eat it when the user presses Enter to
            // prevent the context menu from closing
            return true;
        }

        // Let the base class handle everything else
        return base.ProcessCmdKey(m, keyData);
    }
}

And of course, you could add extra checks to the above code so that the Enter key presses are only eaten when your color picker is visible, allowing things to work as expected all the rest of the time,