且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何防止Enter键关闭菜单

更新时间:2023-12-02 09:55:46

不知何故,您需要先按 Enter 键,然后再按它们进入上下文菜单。显然,它的默认行为是当用户按下 Enter 时选择当前突出显示的项目,就像人类已知的所有其他菜单控件一样。



您可以通过对 ContextMenuStrip 控件进行子类化(如果您尚未这样做)并覆盖其 ProcessCmdKey 方法。观察对应于 Keys的 keyData 值,输入,并在检测到该值时返回 True 表示该字符已被控件处理,并阻止将其传递给任何进一步的处理。当然,其他所有内容都将让基类处理,以便其他键(例如箭头键)的行为保持不变。



例如(我只是经过测试,效果很好): (ref Message m,Keys keyData)
{
if(keyData == Keys.Enter)
{
//当用户按下Enter键时将其吃掉
/ /防止上下文菜单关闭
返回true;
}

//让基类处理其他所有事务
返回base.ProcessCmdKey(m,keyData);
}
}

当然,您可以在上面的代码,以便仅当可见颜色选择器时才按下 Enter 键,这样才能在所有其余时间内按预期方式工作


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.

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,