我正在开发一个Visual Studio扩展,其中一个实现的命令只有在活动文档是文本文档时才可用(例如Visual Studio的“切换书签”)。问题是,我无法弄清楚如何判断这种情况。如何判断活动文档是否为文本文档?
现在我有一半的工作解决方案。在包的Initialize
方法予订阅DTE的WindowActivated
事件,然后每当被激活的窗口余检查窗口DocumentData
属性是TextDocument
类型:
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;
}
这种方法的问题是,1)Window.DocumentData is documented as ".NET Framework internal use only",和2)当在设计模式下打开具有代码视图和设计视图的文档(例如.visxmanifest
文件)时,这会产生误报。
我曾尝试使用IVsTextManager.GetActiveView为好,但这是返回最后活动文本视图中打开 - 所以,如果我打开一个txt文件,然后.png文件,它的.txt文件返回数据,即使如果它不再是活动文档。
那么,如何检查活动文档是文本文档还是可以有设计者的文档的代码视图......并且如果可能,不使用“无证”类/成员?
更新:我发现了一个稍微好一点的解决方案。里面的窗口激活处理程序:
ActiveDocumentIsText = gotFocus.Document.Object("TextDocument") != null;
至少this one is properly documented,但我仍然有设计师误报的问题。