Je développe une extension Visual Studio dans laquelle l'une des commandes implémentées doit être disponible uniquement lorsque le document actif est un document texte (comme par exemple le "Toggle Bookmark" de Visual Studio). Le problème est que je ne peux pas comprendre comment dire quand c'est le cas.Comment savoir si le document actif est un document texte?
Maintenant, j'ai une solution de travail à moitié. Dans la méthode de package Initialize
Je souscris à l'événement WindowActivated
DTE, et chaque fois qu'une fenêtre est activée je vérifie si la fenêtre DocumentData
propriété est de type 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;
}
Le problème avec cette approche est que 1) Window.DocumentData is documented as ".NET Framework internal use only" et 2) cela donne un faux positif quand un document qui a à la fois une vue de code et une vue de conception (par exemple un fichier .visxmanifest
) est ouvert en mode conception.
J'ai essayé d'utiliser IVsTextManager.GetActiveView aussi bien, mais cela revient la dernière vue texte actif ouvert - donc si j'ouvrir un fichier .txt, puis un fichier .png, il renvoie les données pour le fichier txt même si ce n'est plus le document actif.
Alors, comment vérifier si le document actif est un document texte, ou la vue de code d'un document qui peut avoir un concepteur ... et si possible, ne pas utiliser des classes/membres "non documentés"?
MISE À JOUR: J'ai trouvé une solution légèrement meilleure. Dans la fenêtre gestionnaire activée:
ActiveDocumentIsText = gotFocus.Document.Object("TextDocument") != null;
Au moins this one is properly documented, mais je dois encore le problème des faux positifs avec les concepteurs.