Журнал действий отмены / повтора в расширении Visual Studio - PullRequest
4 голосов
/ 18 февраля 2012

Я написал расширение для Visual Studio и веду журнал действий пользователя, связанных с моим расширением. Я хочу иметь возможность включать информацию об отмене / возврате для изменений, которые мой инструмент вносит в журнал, что я ожидаю, чтобы иметь возможность вызывать прослушиватель событий, когда происходит отмена / повтор, и проверять, является ли объект отмены / повторения тот, который соответствует действию, сгенерированному моим инструментом.

В настоящее время у меня есть код для получения ITextUndoHistory для текущего IWpfTextView, который я получаю, используя ITextUndoHistoryRegistry, за которым я следовал этот ответ для генерации. К сожалению, объект ITextUndoHistory, который я получаю, не обладает достаточной функциональностью, чтобы быть полезным. В частности, вызывается его событие UndoRedoHappened, но транзакция всегда имеет значение null. Кроме того, его UndoStack / RedoStack свойства бросают System.NotSupportedException. Единственное, что работает, это CreateTransaction, который дает мне объект транзакции и позволяет мне задать имя для действия, отображаемого в списке отмен / повторов Visual Studio, хотя мне это не нужно.

Есть ли другой способ получить доступ к информации об отмене в Visual Studio? Или, может быть, более творческий взлом с тем, что у меня есть доступ?

1 Ответ

4 голосов
/ 18 февраля 2012

Я предполагаю, что вы хотите регистрировать отмены / повторы команд вашего расширения редактора.Если это не так ... приведенное ниже описание не будет полезным.: -)

Сначала вы хотите создать небольшой класс, производный от ITextUndoPrimitive, представляющий небольшую «операцию», которая включена в часть транзакции отмены.Это имеет два важных метода: Undo(), который вызывается, когда пользователь отменяет транзакцию, и Do(), который вызывается, если пользователь отменяет транзакцию, а затем нажимает кнопку Повторить.Для остальных методов просто выполните тривиальную реализацию: CanUndo / CanRedo всегда должно возвращать true и сделать Parent простым свойством чтения / записи.CanMerge всегда должен возвращать false, и вы можете оставить Merge() не реализованным.Конечно, вы можете хранить любое дополнительное состояние в ITextUndoPrimitive.

Что касается того, что вы делаете в Do / Undo, это ваше дело.Так что если ваше расширение, скажем, изменяет текстовый буфер, а также записывает в какой-то другой файл в проекте пользователя, вы можете отменить запись файла.Я чувствую, что вы просто пытаетесь отследить, какие операции отменил пользователь (возможно, в статистических целях?), И поэтому вы можете просто обновить бит «пользователь отменил это» в своем журнале и покончить с этим.

Когда вы выполняете свое действие, вызовите CreateTransaction, чтобы начать новую транзакцию, а затем в этой транзакции вызовите AddUndo (), передав новый экземпляр вашего примитива отмены.Затем редактор будет вызывать Do / Undo, как описано соответствующим образом.

Последнее замечание: редактор автоматически избавится от отмененных транзакций, когда либо история транзакций становится слишком длинной, либо в некоторых случаях, когда историяуничтожен и его надо сбросить.Поэтому ожидайте, что в какой-то момент ваши отмененные примитивы уйдут и будут GC'ed.Самое главное: не держите их в каком-то другом месте, которое может привести к утечке.

...