Partager via


Procédure pas à pas : Afficher les info-bulles QuickInfo

QuickInfo est une fonctionnalité IntelliSense qui affiche les signatures de méthode et les descriptions lorsqu’un utilisateur déplace le pointeur sur un nom de méthode. Vous pouvez implémenter des fonctionnalités basées sur le langage telles que QuickInfo en définissant les identificateurs pour lesquels vous souhaitez fournir des descriptions QuickInfo, puis en créant une info-bulle dans laquelle afficher le contenu. Vous pouvez définir QuickInfo dans le contexte d’un service de langage, ou vous pouvez définir votre propre extension de nom de fichier et votre propre type de contenu et afficher QuickInfo pour ce type, ou vous pouvez afficher QuickInfo pour un type de contenu existant (par exemple, « text »). Cette procédure pas à pas montre comment afficher QuickInfo pour le type de contenu « text ».

L’exemple QuickInfo de cette procédure pas à pas affiche les info-bulles lorsqu’un utilisateur déplace le pointeur sur un nom de méthode. Cette conception vous oblige à implémenter ces quatre interfaces :

  • interface source

  • interface du fournisseur source

  • interface du contrôleur

  • interface du fournisseur de contrôleur

    Les fournisseurs de sources et de contrôleurs sont des composants MEF (Managed Extensibility Framework), et sont responsables de l’exportation des classes source et du contrôleur et de l’importation de services et de répartiteurs tels que le ITextBufferFactoryService, qui crée la mémoire tampon de texte d’info-bulle et le IQuickInfoBroker, qui déclenche la session QuickInfo.

    Dans cet exemple, la source QuickInfo utilise une liste codée en dur de noms et de descriptions de méthodes, mais dans des implémentations complètes, le service de langage et la documentation linguistique sont responsables de la fourniture de ce contenu.

Créer un projet MEF

Pour créer un projet MEF

  1. Créez un projet VSIX C#. (Dans le Boîte de dialogue Nouveau projet , sélectionnez Visual C# / Extensibilité, puis VSIX Project.) Nommez la solution QuickInfoTest.

  2. Ajoutez un modèle d’élément Classifieur d’éditeur au projet. Pour plus d’informations, consultez Créer une extension avec un modèle d’élément d’éditeur.

  3. Supprimez les fichiers de classe existants.

Implémenter la source QuickInfo

La source QuickInfo est chargée de collecter l’ensemble d’identificateurs et leurs descriptions et d’ajouter le contenu à la mémoire tampon de texte d’info-bulle lorsque l’un des identificateurs est rencontré. Dans cet exemple, les identificateurs et leurs descriptions sont simplement ajoutés dans le constructeur source.

Pour implémenter la source QuickInfo

  1. Ajoutez un fichier de classe et nommez-le TestQuickInfoSource.

  2. Ajoutez une référence à Microsoft.VisualStudio.Language.IntelliSense.

  3. Ajoutez les importations suivantes.

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel.Composition;
    using Microsoft.VisualStudio.Language.Intellisense;
    using Microsoft.VisualStudio.Text;
    using Microsoft.VisualStudio.Text.Editor;
    using Microsoft.VisualStudio.Text.Operations;
    using Microsoft.VisualStudio.Text.Tagging;
    using Microsoft.VisualStudio.Utilities;
    
  4. Déclarez une classe qui implémente IQuickInfoSource, et nommez-la TestQuickInfoSource.

    internal class TestQuickInfoSource : IQuickInfoSource
    
  5. Ajoutez des champs pour le fournisseur source QuickInfo, la mémoire tampon de texte et un ensemble de noms de méthode et de signatures de méthode. Dans cet exemple, les noms et signatures de méthode sont initialisés dans le TestQuickInfoSource constructeur.

    private TestQuickInfoSourceProvider m_provider;
    private ITextBuffer m_subjectBuffer;
    private Dictionary<string, string> m_dictionary;
    
  6. Ajoutez un constructeur qui définit le fournisseur source QuickInfo et la mémoire tampon de texte, puis renseignez l’ensemble de noms de méthode, ainsi que les signatures et descriptions des méthodes.

    public TestQuickInfoSource(TestQuickInfoSourceProvider provider, ITextBuffer subjectBuffer)
    {
        m_provider = provider;
        m_subjectBuffer = subjectBuffer;
    
        //these are the method names and their descriptions
        m_dictionary = new Dictionary<string, string>();
        m_dictionary.Add("add", "int add(int firstInt, int secondInt)\nAdds one integer to another.");
        m_dictionary.Add("subtract", "int subtract(int firstInt, int secondInt)\nSubtracts one integer from another.");
        m_dictionary.Add("multiply", "int multiply(int firstInt, int secondInt)\nMultiplies one integer by another.");
        m_dictionary.Add("divide", "int divide(int firstInt, int secondInt)\nDivides one integer by another.");
    }
    
  7. Implémentez la méthode AugmentQuickInfoSession. Dans cet exemple, la méthode recherche le mot actuel ou le mot précédent si le curseur se trouve à la fin d’une ligne ou d’une mémoire tampon de texte. Si le mot est l’un des noms de méthode, la description de ce nom de méthode est ajoutée au contenu QuickInfo.

    public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> qiContent, out ITrackingSpan applicableToSpan)
    {
        // Map the trigger point down to our buffer.
        SnapshotPoint? subjectTriggerPoint = session.GetTriggerPoint(m_subjectBuffer.CurrentSnapshot);
        if (!subjectTriggerPoint.HasValue)
        {
            applicableToSpan = null;
            return;
        }
    
        ITextSnapshot currentSnapshot = subjectTriggerPoint.Value.Snapshot;
        SnapshotSpan querySpan = new SnapshotSpan(subjectTriggerPoint.Value, 0);
    
        //look for occurrences of our QuickInfo words in the span
        ITextStructureNavigator navigator = m_provider.NavigatorService.GetTextStructureNavigator(m_subjectBuffer);
        TextExtent extent = navigator.GetExtentOfWord(subjectTriggerPoint.Value);
        string searchText = extent.Span.GetText();
    
        foreach (string key in m_dictionary.Keys)
        {
            int foundIndex = searchText.IndexOf(key, StringComparison.CurrentCultureIgnoreCase);
            if (foundIndex > -1)
            {
                applicableToSpan = currentSnapshot.CreateTrackingSpan
                    (
                    //querySpan.Start.Add(foundIndex).Position, 9, SpanTrackingMode.EdgeInclusive
                                            extent.Span.Start + foundIndex, key.Length, SpanTrackingMode.EdgeInclusive
                    );
    
                string value;
                m_dictionary.TryGetValue(key, out value);
                if (value != null)
                    qiContent.Add(value);
                else
                    qiContent.Add("");
    
                return;
            }
        }
    
        applicableToSpan = null;
    }
    
  8. Vous devez également implémenter une méthode Dispose(), car IQuickInfoSource implémente IDisposable:

    private bool m_isDisposed;
    public void Dispose()
    {
        if (!m_isDisposed)
        {
            GC.SuppressFinalize(this);
            m_isDisposed = true;
        }
    }
    

Implémenter un fournisseur de source QuickInfo

Le fournisseur de la source QuickInfo sert principalement à s’exporter en tant que composant MEF et instancier la source QuickInfo. Étant donné qu’il s’agit d’une partie de composant MEF, il peut importer d’autres composants de composant MEF.

Pour implémenter un fournisseur de source QuickInfo

  1. Déclarez un fournisseur de source QuickInfo nommé TestQuickInfoSourceProvider qui implémente IQuickInfoSourceProvider, puis exportez-le avec une NameAttribute « source QuickInfo info-bulle », une OrderAttribute source Before=«default » et un ContentTypeAttribute « text ».

    [Export(typeof(IQuickInfoSourceProvider))]
    [Name("ToolTip QuickInfo Source")]
    [Order(Before = "Default Quick Info Presenter")]
    [ContentType("text")]
    internal class TestQuickInfoSourceProvider : IQuickInfoSourceProvider
    
  2. Importez deux services d’éditeur et ITextStructureNavigatorSelectorServiceITextBufferFactoryService, en tant que propriétés de TestQuickInfoSourceProvider.

    [Import]
    internal ITextStructureNavigatorSelectorService NavigatorService { get; set; }
    
    [Import]
    internal ITextBufferFactoryService TextBufferFactoryService { get; set; }
    
  3. Implémenter TryCreateQuickInfoSource pour retourner un nouveau TestQuickInfoSource.

    public IQuickInfoSource TryCreateQuickInfoSource(ITextBuffer textBuffer)
    {
        return new TestQuickInfoSource(this, textBuffer);
    }
    

Implémenter un contrôleur QuickInfo

Les contrôleurs QuickInfo déterminent quand QuickInfo est affiché. Dans cet exemple, QuickInfo s’affiche lorsque le pointeur se trouve sur un mot qui correspond à l’un des noms de méthode. Le contrôleur QuickInfo implémente un gestionnaire d’événements de pointage de souris qui déclenche une session QuickInfo.

Pour implémenter un contrôleur QuickInfo

  1. Déclarez une classe qui implémente IIntellisenseController, et nommez-la TestQuickInfoController.

    internal class TestQuickInfoController : IIntellisenseController
    
  2. Ajoutez des champs privés pour l’affichage de texte, les mémoires tampons de texte représentées dans l’affichage texte, la session QuickInfo et le fournisseur de contrôleur QuickInfo.

    private ITextView m_textView;
    private IList<ITextBuffer> m_subjectBuffers;
    private TestQuickInfoControllerProvider m_provider;
    private IQuickInfoSession m_session;
    
  3. Ajoutez un constructeur qui définit les champs et ajoute le gestionnaire d’événements de pointage de la souris.

    internal TestQuickInfoController(ITextView textView, IList<ITextBuffer> subjectBuffers, TestQuickInfoControllerProvider provider)
    {
        m_textView = textView;
        m_subjectBuffers = subjectBuffers;
        m_provider = provider;
    
        m_textView.MouseHover += this.OnTextViewMouseHover;
    }
    
  4. Ajoutez le gestionnaire d’événements de pointage de la souris qui déclenche la session QuickInfo.

    private void OnTextViewMouseHover(object sender, MouseHoverEventArgs e)
    {
        //find the mouse position by mapping down to the subject buffer
        SnapshotPoint? point = m_textView.BufferGraph.MapDownToFirstMatch
             (new SnapshotPoint(m_textView.TextSnapshot, e.Position),
            PointTrackingMode.Positive,
            snapshot => m_subjectBuffers.Contains(snapshot.TextBuffer),
            PositionAffinity.Predecessor);
    
        if (point != null)
        {
            ITrackingPoint triggerPoint = point.Value.Snapshot.CreateTrackingPoint(point.Value.Position,
            PointTrackingMode.Positive);
    
            if (!m_provider.QuickInfoBroker.IsQuickInfoActive(m_textView))
            {
                m_session = m_provider.QuickInfoBroker.TriggerQuickInfo(m_textView, triggerPoint, true);
            }
        }
    }
    
  5. Implémentez la Detach méthode afin qu’elle supprime le gestionnaire d’événements de pointage de la souris lorsque le contrôleur est détaché de la vue de texte.

    public void Detach(ITextView textView)
    {
        if (m_textView == textView)
        {
            m_textView.MouseHover -= this.OnTextViewMouseHover;
            m_textView = null;
        }
    }
    
  6. Implémentez la ConnectSubjectBuffer méthode et la DisconnectSubjectBuffer méthode en tant que méthodes vides pour cet exemple.

    public void ConnectSubjectBuffer(ITextBuffer subjectBuffer)
    {
    }
    
    public void DisconnectSubjectBuffer(ITextBuffer subjectBuffer)
    {
    }
    

Implémentation du fournisseur de contrôleur QuickInfo

Le fournisseur du contrôleur QuickInfo sert principalement à s’exporter en tant que composant MEF et à instancier le contrôleur QuickInfo. Étant donné qu’il s’agit d’une partie de composant MEF, il peut importer d’autres composants de composant MEF.

Pour implémenter le fournisseur de contrôleur QuickInfo

  1. Déclarez une classe nommée TestQuickInfoControllerProvider qui implémente IIntellisenseControllerProvider, puis exportez-la avec un NameAttribute « ToolTip QuickInfo Controller » et un ContentTypeAttribute « text » :

    [Export(typeof(IIntellisenseControllerProvider))]
    [Name("ToolTip QuickInfo Controller")]
    [ContentType("text")]
    internal class TestQuickInfoControllerProvider : IIntellisenseControllerProvider
    
  2. Importez le IQuickInfoBroker en tant que propriété.

    [Import]
    internal IQuickInfoBroker QuickInfoBroker { get; set; }
    
  3. Implémentez la TryCreateIntellisenseController méthode en instanciant le contrôleur QuickInfo.

    public IIntellisenseController TryCreateIntellisenseController(ITextView textView, IList<ITextBuffer> subjectBuffers)
    {
        return new TestQuickInfoController(textView, subjectBuffers, this);
    }
    

Générer et tester le code

Pour tester ce code, générez la solution QuickInfoTest et exécutez-la dans l’instance expérimentale.

Pour générer et tester la solution QuickInfoTest

  1. Générez la solution.

  2. Lorsque vous exécutez ce projet dans le débogueur, une deuxième instance de Visual Studio est démarrée.

  3. Créez un fichier texte et tapez du texte incluant les mots « add » et « soustrait ».

  4. Déplacez le pointeur sur l’une des occurrences de « add ». La signature et la description de la add méthode doivent être affichées.