如何为文本框重写ShortcutsEnabled

时间:2017-03-28 18:00:19

标签: c# winforms textbox

如何覆盖文本框的ShortcutsEnabled属性以接受某些快捷方式并拒绝其他内容?

clearify:我尝试在textbox上创建一个组件库,并将其context menu更改为更漂亮的组件。为了显示我的context menu我首先使用contextMenu/contextMenuStrip属性测试了2种方法,但它有问题(如果用户按下鼠标右键并移出并离开按钮,此方法将无效)另一种方法是使用效果很好的ShortcutsEnabled属性。但我喜欢像ctrl + C这样的快捷方式,......保持活跃状态​​。 here表示可以覆盖此属性以指定快捷方式,但我找不到任何有关如何完成此操作的示例。

编辑:我没有找到这样做的好方法。但为了解决我的问题(启用快捷方式时禁用上下文菜单)我找到了@AliTheOne和@ x5657提供的链接的解决方案。您可以在0x007B message中抓住WndProc,好消息是您仍然可以在right mouse button click中抓住mouse down event并使用它来显示自定义上下文菜单,并且不会显示正常的上下文菜单。请注意,这将启用所有正常的快捷方式。

protected override void WndProc(ref Message m)
            {
                if (m.Msg != 0x007B)
                {
                    base.WndProc(ref m);
                }
            }

void textBox_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                //show custom context menu

            }
        }

2 个答案:

答案 0 :(得分:0)

基于code for textbox,我认为您需要覆盖ProcessCmdKey。

基本ShortcutsEnabled setter设置在shortcutsToDisable字段中启用了哪些快捷方式,但不幸的是,这是私有的,因此您必须自己滚动自己的"实施

ProcessCmdKey看起来像这样:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { 
    if (this.ShortcutsEnabled == false) {
        foreach (int shortcutValue in shortcutsToDisable) {
            if ((int)keyData == shortcutValue ||
                (int)keyData == (shortcutValue | (int)Keys.Shift)) { 
                return true;
            } 
        } 
    }
    // 
    // There are a few keys that change the alignment of the text, but that
    // are not ignored by the native control when the ReadOnly property is set.
    // We need to workaround that.
    if (textBoxFlags[readOnly]) { 
        int k = (int)keyData;
        if (k == (int)Shortcut.CtrlL        // align left 
            || k == (int)Shortcut.CtrlR     // align right 
            || k == (int)Shortcut.CtrlE     // align centre
            || k == (int)Shortcut.CtrlJ) {  // align justified 
            return true;
        }
    }

    return base.ProcessCmdKey(ref msg, keyData);
} 

答案 1 :(得分:0)

基于此:Using Prepared Statements

您可以执行此操作:我们希望通过Ctrl + R和Ctrl + L

设置对齐方式

如果您要禁用任何内置快捷方式,例如Ctrl + Z并为其指定新方法,只需将其从public override bool ShortcutsEnabled {}中删除并将其放入protected override bool ProcessCmdKey(..)switch..case

     public class MyTextBox : TextBox
     {

    private static readonly int _readOnly = BitVector32.CreateMask();
    private static readonly int _shortcutsEnabled = BitVector32.CreateMask(_readOnly);
    private static int[] _shortcutsToDisable;

    private BitVector32 _textBoxFlags;

    public override bool ShortcutsEnabled
    {
        get { return _textBoxFlags[_shortcutsEnabled]; }
        set
        {
            if (_shortcutsToDisable == null)
            {
                _shortcutsToDisable = new int[]
                {
                    (int) Shortcut.CtrlZ,(int) Shortcut.CtrlC, (int) Shortcut.CtrlX,
                    (int) Shortcut.CtrlV, (int) Shortcut.CtrlA, (int) Shortcut.CtrlL, (int) Shortcut.CtrlR,
                    (int) Shortcut.CtrlE, (int) Shortcut.CtrlY, (int) Keys.Control + (int) Keys.Back,
                    (int) Shortcut.CtrlDel, (int) Shortcut.ShiftDel, (int) Shortcut.ShiftIns, (int) Shortcut.CtrlJ
                };
            }
            _textBoxFlags[_shortcutsEnabled] = value;

        }
    }
    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        if (_shortcutsToDisable == null)
        {
            return false;
        }
            var k = (int)keyData;
        switch (k)
        {
            case (int)Shortcut.CtrlL:
                TextAlign=HorizontalAlignment.Left;
               break;
            case (int)Shortcut.CtrlR:
                TextAlign = HorizontalAlignment.Right;
                break;
            default:
                return base.ProcessCmdKey(ref msg, keyData);
        }
        return true;
    }
}