CodeGo.net>如何管理VSPackage中的撤消/重做堆栈?
作者:互联网
我创建了VSPackage,它在Visual Studio代码窗口上下文菜单中提供了某些功能.此操作包括几个代码编辑以及一些相关内容.
问题是,这些代码编辑中的每一个都分别添加到撤消堆栈中.我想要将这个动作作为一个原子单位来处理,即按CTRL Z会回滚所有代码编辑以及其他所有内容(当然,还要将该单位放在重做堆栈的顶部).
关于该主题的文档非常差,我发现的唯一内容是有关IOleParentUndo单元的信息-但我在实现它方面并不成功.
我用
IVsTextLines.GetUndoManager()
获取撤消管理器-这似乎是一个好的开始.
解决方法:
如果在文档级别管理撤消,那么您可能必须使用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);
}
}
}
标签:vspackage,vsx,c 来源: https://codeday.me/bug/20191101/1983022.html