撤消缓冲区清除后处理OnKeyDown在文本框
本文关键字:文本 OnKeyDown 后处理 缓冲区 清除 撤消 | 更新日期: 2023-09-27 18:01:41
我正在子类化TextBox:
class Editor : TextBox
我已经重写了OnKeyDown,因为我想用四个空格替换制表符:
protected override void OnKeyDown(KeyEventArgs e)
{
if (e.KeyCode == Keys.Tab) {
SelectedText = " ";
e.SuppressKeyPress = true;
}
}
这是可行的,但不幸的是它也会清除undo缓冲区。最终的结果是,当用户按tab键时,Ctrl+Z不起作用,右键菜单上的"撤消"功能被禁用。问题似乎是"e.p suppresskeypress = true;"部分。
有谁知道如何解决这个问题吗?
更多信息,我正在创建一个相当简单的文本编辑器,我不仅处理Tab键(如上所述),而且还处理Enter键。我在按Tab键和回车键时遇到了这个问题。我知道这个问题不存在与RichTextBox,但出于各种原因,我想使用TextBox代替。
任何帮助都将非常感激,因为这是我项目中一个引人注目的问题。
谢谢,汤姆
这不是重写OnKeyDown
的结果,而是您设置了SelectedText
(任何文本修改都会产生相同的效果)。您可以通过注释掉设置SelectedText
而留下其他所有内容的代码来看到这一点。显然,你不会得到一个制表符或四个字符,但撤销缓冲区将被保留。
根据这篇博客文章,你应该能够使用Paste(string)
函数,而不是设置SelectedText
属性,并保留撤消缓冲区:
protected override void OnKeyDown(KeyEventArgs e)
{
if (e.KeyCode == Keys.Tab)
{
Paste(" ");
e.SuppressKeyPress = true;
}
}
我终于找到了解决方案,这是使用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;
}