使用Word UndoRecord接口时,如何在撤销前获取用户输入?
解决UndoRecord结束前获取用户输入的问题
我明白你现在的需求:在Word里用UndoRecord管理计算操作的撤销,但想在结束撤销记录前先获取用户输入,再决定是否保留操作对吧?咱们先看看你现有代码的问题,再给出针对性的解决方案。
首先,你当前用MessageBox来获取确认,但如果是要让用户在Word文档里实际输入内容,直接在StartCustomRecord之后让用户输入的话,用户的输入会被包含在这个自定义撤销组里——这可能不是你想要的,因为撤销时会把计算和用户输入一起删掉。咱们分两种常见场景来处理:
场景1:只撤销计算,保留用户输入
如果你的需求是先执行计算,让用户补充输入内容,最后用户可以选择只撤销计算、保留自己的输入,那得调整撤销记录的时机:
private static void Run_Calc() { Word.Application wordApp; Word.Document oDoc = null; wordApp = (Word.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Word.Application"); oDoc = wordApp.ActiveDocument; Word.UndoRecord Un = wordApp.UndoRecord; // 先把计算操作包裹在撤销记录里 Un.StartCustomRecord("文档计算操作"); // --- 这里放你的计算逻辑代码 --- Un.EndCustomRecord(); // 现在让用户自由输入,这部分不会被计入撤销组 MessageBox.Show("请在文档中添加你的输入,完成后点击确定", "输入提示"); // 询问用户是否保留计算结果 DialogResult D = MessageBox.Show("是否保留刚才的计算操作?", "确认", MessageBoxButtons.YesNo); if (D.Equals(DialogResult.No)) { // 只撤销之前的计算操作,用户输入不受影响 oDoc.Undo(); } }
这里的核心是:先结束计算的撤销记录,再让用户输入,这样用户的输入和计算操作是两个独立的撤销单元,撤销时只会删掉计算部分。
场景2:计算+用户输入一起撤销
如果你希望用户输入和计算操作被归为一组,一键就能撤销两者,那就要把用户输入也包含在撤销记录的生命周期里:
private static void Run_Calc() { Word.Application wordApp; Word.Document oDoc = null; wordApp = (Word.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Word.Application"); oDoc = wordApp.ActiveDocument; Word.UndoRecord Un = wordApp.UndoRecord; // 启动撤销组,后续的计算和用户输入都会被包含进来 Un.StartCustomRecord("计算+用户输入"); // 先执行你的计算逻辑 // --- 这里放计算代码 --- // 等待用户完成输入(用模态对话框阻塞,确保用户输入完再继续) DialogResult inputCompleted = MessageBox.Show("请在文档中添加输入,完成后点击确定", "输入提示", MessageBoxButtons.OK); if (inputCompleted == DialogResult.OK) { Un.EndCustomRecord(); // 询问用户是否保留整个操作组 DialogResult keepChanges = MessageBox.Show("是否保留计算和你的输入内容?", "确认", MessageBoxButtons.YesNo); if (keepChanges == DialogResult.No) { // 一键撤销计算+用户输入 oDoc.Undo(); } } else { // 用户取消输入,直接结束并撤销整个组 Un.EndCustomRecord(); oDoc.Undo(); } }
几个关键提醒
- 一定要保证
StartCustomRecord和EndCustomRecord成对出现,不然会打乱Word的撤销栈,导致奇怪的问题。 - 如果不用模态对话框等待用户输入,要注意别阻塞Word的UI线程,不然会导致程序无响应。
- 你原代码里的
Undo_it变量没用到,可以删掉让代码更整洁。
内容的提问来源于stack exchange,提问作者Doicare




