Если отмена управляется на уровне документа, то вы, возможно, придется с помощью RunningDocumentTable перечислить таблицы, получить их менеджеров отменяющее и атомную бомбу с орбиты:
class NavigateListener: IVsRunningDocTableEvents3
{
private HashSet<IVsTextView> views = new HashSet<IVsTextView>();
private IVsRunningDocumentTable table;
private uint cookie;
...
Снаружи называют этот регистр вызова - добавьте незарегистрированный вызов, который предотвращает события.
public void Register()
{
table =(IVsRunningDocumentTable) Package.GetGlobalService(typeof(SVsRunningDocumentTable));
// Listen to show/hide events of docs to register activate/deactivate cursor listeners.
table.AdviseRunningDocTableEvents(this, out cookie);
}
Ходовая таблица имеет много событий, как сохранить и т.д., но вы можете слушать, когда регистрируется вид:
public int OnAfterDocumentWindowHide(uint docCookie, IVsWindowFrame pFrame)
{
IVsTextView view = VsShellUtilities.GetTextView(pFrame);
if (view != null)
{
views.Add(view);
}
}
вас могут возникнуть проблемы с документами, которые были изменения сохранены, но затем были закрыты ... удалить их на данный момент ...
public int OnBeforeDocumentWindowShow(uint docCookie, int fFirstShow, IVsWindowFrame pFrame)
{
IVsTextView view = VsShellUtilities.GetTextView(pFrame);
if (view != null)
{
views.Remove(view);
}
return VSConstants.S_OK;
}
Тогда вы можете сделать супер уничтожить ядерное оружие. Я не тестировал эту часть - вам придется поиграть с ней.
private void NukeFromOrbit()
{
foreach(var view in views)
{
IVsTextLines buffer;
view.GetBuffer(out buffer);
IOleUndoManager manager;
buffer.GetUndoManager(out manager);
IEnumOleUndoUnits units;
manager.EnumUndoable(out units);
uint fetched=0;
var unitArray = new IOleUndoUnit[1];
while(units.Next(1, unitArray , out fetched) == VSConstants.S_OK)
{
unitArray[0].Do(manager);
}
}
}
Я на самом деле придумал таким решением самого - но это здорово знать, что нет ничего лучше, спасибо :-) – cre8or
+1 для эпического имени методы! – akuhn