.NET RichTextBox代码修改文本不记录撤销,如何开启该功能?
让RichTextBox代码修改操作纳入撤销队列的解决方案
嘿,这个问题我之前也碰到过!WinForms的RichTextBox确实有这么个小特性——直接给Text属性赋值的操作不会被放进撤销队列里,因为它被设计成一次性的批量替换,默认不触发撤销记录。不过不用自己费劲跟踪所有变更,有两个简单的方法能解决这个问题:
方法1:通过SelectedText替换全部内容
先选中RichTextBox里的所有文本,然后给SelectedText赋值,这样的修改会被当作和用户手动编辑一样的操作,自动加入撤销队列:
// 选中控件内所有文本 richTextBox1.SelectAll(); // 替换选中内容,这个操作会被记录到撤销栈 richTextBox1.SelectedText = "somestring";
之后调用richTextBox1.Undo()就能正常撤销这次代码修改了,和手动编辑的撤销逻辑完全一致。
方法2:底层调用Windows消息EM_REPLACESEL
如果需要更精细的控制,可以直接给RichTextBox发送EM_REPLACESEL系统消息,这个消息本身就会触发撤销记录:
using System.Runtime.InteropServices; [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern int SendMessage(IntPtr hWnd, int msg, int wParam, string lParam); private const int EM_REPLACESEL = 0xC2; // 调用示例 richTextBox1.SelectAll(); // wParam设为1表示允许这次操作被撤销,设为0则不允许 SendMessage(richTextBox1.Handle, EM_REPLACESEL, 1, "somestring");
其实SelectedText的内部实现就是调用这个消息,但如果你需要灵活控制是否允许撤销,这个方法会更合适。
补充:为什么直接赋值Text不行?
直接设置Text属性会绕过RichTextBox的编辑操作跟踪机制,它会直接重置控件的内容,不会生成对应的撤销单元。而通过选中替换的方式,走的是和用户手动输入、删除相同的编辑流程,所以会被自动记录到撤销栈中。
内容的提问来源于stack exchange,提问作者Jonas Kohl
相关产品推荐
相关产品推荐

