在 Visual Studio 扩展中记录撤消/重做操作

发布于 2025-01-06 23:11:37 字数 690 浏览 4 评论 0原文

我编写了一个 Visual Studio 扩展,并让它保留与我的扩展相关的用户操作日志。我希望能够在日志中包含我的工具所做的更改的撤消/重做信息,我希望能够通过在发生撤消/重做时调用事件侦听器来完成此操作,并检查撤消/重做对象是否为与我的工具生成的操作相对应的一个。

目前,我有代码来获取当前 IWpfTextViewITextUndoHistory ,我使用我遵循的 ITextUndoHistoryRegistry 来获取它 此答案生成。不幸的是,我得到的 ITextUndoHistory 对象没有实现足够有用的功能。具体来说,它的 UndoRedoHappened 事件被调用,但始终有一个 null 事务。此外,其 UndoStack/RedoStack 属性会抛出 System.NotSupportedException。唯一有效的是 CreateTransaction 确实为我提供了一个事务对象,并让我为 Visual Studio 的撤消/重做列表中显示的操作设置名称,尽管我不需要它来工作。

是否有其他方法可以访问 Visual Studio 中的撤消信息?或者也许我可以利用一些更有创意的技巧?

I have written a Visual Studio extension and I have it keep a log of user actions related to my extension. I want to be able to include undo/redo information for changes that my tool makes in the log, which I expect to be able to do by having an event listener called when an undo/redo occurs and check if the undo/redo object is the one corresponding to an action that my tool generated.

Currently, I have code to get the ITextUndoHistory for the current IWpfTextView, which I get using an ITextUndoHistoryRegistry which I followed this answer to generate. Unfortunately, the ITextUndoHistory object I get does not implement enough of the functionality to be useful. Specifically, its UndoRedoHappened event gets called, but always has a transaction of null. Also, its UndoStack/RedoStack properties throw System.NotSupportedException. The only thing that does work is CreateTransaction does give me a transaction object and lets me set the name for the action displayed in Visual Studio's undo/redo list, although I don't need that to work.

Is there some other way to access undo information in Visual Studio? Or maybe some more creative hack with what I have access to?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

三月梨花 2025-01-13 23:11:37

我假设您想要记录您的编辑器扩展命令的撤消/重做。如果情况并非如此……下面的描述将没有用处。 :-)

您首先要做的是创建一个派生自 ITextUndoPrimitive 的小类,它表示包含在撤消事务一部分中的小“操作”。它有两个重要的方法:Undo(),当用户撤消交易时调用;Do(),当用户撤消交易然后点击重做时调用。对于其余方法,只需执行简单的实现即可:CanUndo/CanRedo 应始终返回 true,并使 Parent 成为一个简单的读/写属性。 CanMerge 应始终返回 false,并且您可以不实现 Merge()。当然,您可以在 ITextUndoPrimitive 中保留所需的任何其他状态。

至于您在“执行/撤消”中执行的操作,这取决于您。因此,如果您的扩展是修改文本缓冲区并写入用户项目中的其他文件,您可以撤消文件写入。我觉得你只是想跟踪用户取消了哪些操作(也许是出于统计目的?),所以你可能只是更新日志中的“用户取消了这个”位并完成它。

当您执行操作时,调用 CreateTransaction 来启动新事务,然后在该事务上调用 AddUndo() 并传入撤消基元的新实例。然后,编辑器将根据适当的描述调用执行/撤消。

最后一点:当交易历史记录太长,或者在某些情况下历史记录被破坏并且必须重置时,编辑器将自动删除撤消交易。因此,预计在某个时候您的撤消原语将会消失并被 GC 回收。最重要的是:不要将它们放在其他会导致泄漏的地方。

I'm assuming you're wanting to log undo/redos of commands of your editor extension. If that's not the case...this description below won't be useful. :-)

What you want to do first is create a small class that derives from ITextUndoPrimitive which represents a small "operation" that's included in a part of a undo transaction. This has two important methods: Undo() which is called when the user undoes the transaction, and Do() which is called if the user undid the transaction and then hit Redo. For the rest of the methods, just do the trivial implementation: CanUndo/CanRedo should always return true, and make Parent a simple read/write property. CanMerge should always return false, and you can leave Merge() unimplemented. You can of course hold any additional state you want in the ITextUndoPrimitive.

As far as what you do in Do/Undo, that's up to you. So if your extension is, say, modifying the text buffer and also writing to some other file in the user's project, you could undo the file write. I get a sense you're just trying to track which operations the user undid (perhaps for statistical purposes?), and so you might just update a "the user undid this" bit in your log and be done with it.

When you are performing your action, call CreateTransaction to start a new transaction, and then on that transaction call AddUndo() passing in a new instance of your undo primitive. The editor will then call Do/Undo as described as appropriate.

One last note: the editor will automatically get rid of undo transactions when either the transaction history is getting too long, or in some cases where the history is destroyed and it must be reset. So expect that at some point your undo primitives will go away and be GC'ed. Most importantly: don't hold onto them in some other place that would cause them to leak.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文