在TextBox中处理OnKeyDown后,撤消缓冲区被清除

时间:2011-07-11 17:18:56

标签: c# winforms textbox

我正在继承TextBox:

class Editor : TextBox

我已经覆盖了OnKeyDown,因为我希望将标签替换为四个空格:

protected override void OnKeyDown(KeyEventArgs e)
{
    if (e.KeyCode == Keys.Tab) {
        SelectedText = "    ";
        e.SuppressKeyPress = true;
    }
}

这很有效,但不幸的是它也清除了撤消缓冲区。最终结果是,当用户按Tab键时,Ctrl + Z不起作用,右键单击菜单上的“撤消”将被禁用。问题似乎是“e.SuppressKeyPress = true;”一部分。

有没有人知道怎么解决这个问题?

有关详细信息,我正在创建一个相当简单的文本编辑器,我不仅处理Tab键(如上所述),还处理Enter键。 Tab和Enter有这个问题。我知道RichTextBox不存在这个问题,但出于各种原因我想改用TextBox。

任何帮助都会非常感激,因为这是我项目中一个停止显示的问题。

谢谢, 汤姆

2 个答案:

答案 0 :(得分:2)

这不是覆盖OnKeyDown的结果,而是您正在设置SelectedText(任何文本修改都会产生相同的效果)。您可以通过注释掉设置SelectedText的代码,同时保留其他所有内容来查看此内容。显然你不会得到一个标签或四个字符,但是会保留撤消缓冲区。

根据this blog post,您应该能够使用Paste(string)函数而不是设置SelectedText属性并保留撤消缓冲区:

protected override void OnKeyDown(KeyEventArgs e)
{
    if (e.KeyCode == Keys.Tab) 
    {
        Paste("    ");
        e.SuppressKeyPress = true;
    }
}

答案 1 :(得分:0)

我终于找到了解决方案,即使用Windows API,如下所示:

protected override void OnKeyDown(KeyEventArgs e)
{
    if (e.KeyCode == Keys.Tab) {
        WinApi.SendMessage(Handle, WinApi.WmChar, WinApi.VkSpace, (IntPtr)4);
        e.SuppressKeyPress = true;
    }
    base.OnKeyDown(e);
}

这是我的WinApi类:

using System;
using System.Runtime.InteropServices;

class WinApi
{ 
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

    public const           UInt32 WmChar  =         0x102;
    public static readonly IntPtr VkSpace = (IntPtr)0x20;
}