我正在开发一个Visual Studio扩展,其中只有当活动文档是文本文档时才能使用其中一个已实现的命令(例如Visual Studio'' Toggle Bookmark&# 34;确实如此。问题是,我无法弄清楚该怎么回事。
现在我有一个半工作的解决方案。在包的Initialize
方法中,我订阅了DTE的WindowActivated
事件,然后每当窗口被激活时,我都会检查窗口DocumentData
属性是否为{ {1}}:
TextDocument
这种方法的问题在于1)Window.DocumentData is documented as ".NET Framework internal use only",2)当同时具有代码视图和设计视图的文档(例如protected override void Initialize()
{
base.Initialize();
var dte = Package.GetGlobalService(typeof(EnvDTE.DTE)) as EnvDTE.DTE;
dte.Events.WindowEvents.WindowActivated += WindowEventsOnWindowActivated;
//More initialization here...
}
//This is checked from command's BeforeQueryStatus
public bool ActiveDocumentIsText { get; private set; } = false;
private void WindowEventsOnWindowActivated(Window gotFocus, Window lostFocus)
{
if (gotFocus.Kind != "Document")
return; //It's not a document (e.g. it's a tool window)
TextDocument textDoc = gotFocus.DocumentData as TextDocument;
ActiveDocumentIsText = textDoc != null;
}
文件)时,这会产生误报。在设计模式下打开。
我也试过使用IVsTextManager.GetActiveView,但这会返回打开的 last 活动文本视图 - 所以如果我打开.txt文件然后打开.png文件,那么返回.txt文件的数据,即使它不再是活动文档。
那么,我如何检查活动文档是文本文档,还是可以拥有设计者的文档的代码视图......如果可能的话,不使用"未记录的"类/成员?
更新:我找到了一个更好的解决方案。在窗口内激活处理程序:
.visxmanifest
至少this one is properly documented,但我仍然遇到设计师误报的问题。
答案 0 :(得分:0)
我终于明白了。这有点棘手,但它有效,并且是100%"合法"。这是食谱:
1-制作包类实现IVsRunningDocTableEvents。只需return VSConstants.S_OK;
2-将以下字段和以下辅助方法添加到包类:
private IVsRunningDocumentTable runningDocumentTable;
private bool DocIsOpenInLogicalView(string path, Guid logicalView, out IVsWindowFrame windowFrame)
{
return VsShellUtilities.IsDocumentOpen(
this,
path,
VSConstants.LOGVIEWID_TextView,
out var dummyHierarchy2, out var dummyItemId2,
out windowFrame);
}
3-将以下内容添加到包类的Initialize
方法中:
runningDocumentTable = GetService(typeof(SVsRunningDocumentTable)) as IVsRunningDocumentTable;
runningDocumentTable.AdviseRunningDocTableEvents(this, out var dummyCookie);
4- 不要眨眼,这就是魔术!按如下方式实施IVsRunningDocTableEvents.OnBeforeDocumentWindowShow
方法:
public int OnBeforeDocumentWindowShow(uint docCookie, int fFirstShow, IVsWindowFrame pFrame)
{
runningDocumentTable.GetDocumentInfo(docCookie,
out var dummyFlags, out var dummyReadLocks, out var dummyEditLocks,
out string path,
out var dummyHierarchy, out var dummyItemId, out var dummyData);
IVsWindowFrame windowFrameForTextView;
var docIsOpenInTextView =
DocIsOpenInLogicalView(path, VSConstants.LOGVIEWID_Code, out windowFrameForTextView) ||
DocIsOpenInLogicalView(path, VSConstants.LOGVIEWID_TextView, out windowFrameForTextView);
//Is the document open in the code/text view,
//AND the window for that view is the one that has been just activated?
ActiveDocumentIsText = docIsOpenInTextView && pFrame == logicalViewWindowFrame;
return VSConstants.S_OK;
}