Freigeben über


Exemplarische Vorgehensweise: QuickInfo-QuickInfo-QuickInfo anzeigen

QuickInfo ist ein IntelliSense-Feature, das Methodensignaturen und -beschreibungen anzeigt, wenn ein Benutzer den Mauszeiger über einen Methodennamen verschiebt. Sie können sprachbasierte Features wie QuickInfo implementieren, indem Sie die Bezeichner definieren, für die Sie QuickInfo-Beschreibungen bereitstellen möchten, und dann eine QuickInfo-Info erstellen, in der der Inhalt angezeigt werden soll. Sie können QuickInfo im Kontext eines Sprachdiensts definieren oder Eigene Dateinamenerweiterung und Inhaltstyp definieren und die QuickInfo nur für diesen Typ anzeigen oder QuickInfo für einen vorhandenen Inhaltstyp anzeigen (z. B. "Text"). In dieser exemplarischen Vorgehensweise wird gezeigt, wie QuickInfo für den Inhaltstyp "Text" angezeigt wird.

Im QuickInfo-Beispiel in dieser exemplarischen Vorgehensweise werden die QuickInfos angezeigt, wenn ein Benutzer den Mauszeiger über einen Methodennamen verschiebt. Für dieses Design müssen Sie diese vier Schnittstellen implementieren:

  • Quellschnittstelle

  • Quellanbieterschnittstelle

  • Controllerschnittstelle

  • Controlleranbieterschnittstelle

    Die Quell- und Controlleranbieter sind Komponententeile des Managed Extensibility Framework (MEF) und sind für den Export der Quell- und Controllerklassen sowie für den Import von Diensten und Brokern wie dem ITextBufferFactoryService, der den QuickInfo-Textpuffer erstellt, und der IQuickInfoBroker, der die QuickInfo-Sitzung auslöst, verantwortlich.

    In diesem Beispiel verwendet die QuickInfo-Quelle eine hartcodierte Liste von Methodennamen und Beschreibungen, aber in vollständigen Implementierungen sind der Sprachdienst und die Sprachdokumentation für die Bereitstellung dieses Inhalts verantwortlich.

Erstellen eines MEF-Projekts

So erstellen Sie ein MEF-Projekt

  1. Erstellen Sie ein C#VSIX-Projekt. (Im Dialogfeld "Neues Projekt ", wählen Sie Visual C# / Erweiterbarkeit und dann VSIX-Projekt aus.) Benennen Sie die Lösung QuickInfoTest.

  2. Fügen Sie dem Projekt eine Elementvorlage für Editorklassifizierer hinzu. Weitere Informationen finden Sie unter Erstellen einer Erweiterung mit einer Editorelementvorlage.

  3. Löschen Sie die vorhandenen Klassendateien.

Implementieren der QuickInfo-Quelle

Die QuickInfo-Quelle ist dafür verantwortlich, die Gruppe von Bezeichnern und deren Beschreibungen zu sammeln und den Inhalt dem QuickInfo-Textpuffer hinzuzufügen, wenn eine der Bezeichner gefunden wird. In diesem Beispiel werden die Bezeichner und ihre Beschreibungen soeben im Quellkonstruktor hinzugefügt.

So implementieren Sie die QuickInfo-Quelle

  1. Fügen Sie eine Klassendatei hinzu, und nennen Sie sie TestQuickInfoSource.

  2. Fügen Sie einen Verweis auf Microsoft.VisualStudio.Language.IntelliSense hinzu.

  3. Fügen Sie die folgenden Importe hinzu.

    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. Deklarieren Sie eine Klasse, die sie implementiert IQuickInfoSource, und nennen Sie sie TestQuickInfoSource.

    internal class TestQuickInfoSource : IQuickInfoSource
    
  5. Fügen Sie Felder für den QuickInfo-Quellanbieter, den Textpuffer und eine Reihe von Methodennamen und Methodensignaturen hinzu. In diesem Beispiel werden die Methodennamen und Signaturen im TestQuickInfoSource Konstruktor initialisiert.

    private TestQuickInfoSourceProvider m_provider;
    private ITextBuffer m_subjectBuffer;
    private Dictionary<string, string> m_dictionary;
    
  6. Fügen Sie einen Konstruktor hinzu, der den QuickInfo-Quellanbieter und den Textpuffer festlegt, und füllt den Satz von Methodennamen und Methodensignaturen und -beschreibungen auf.

    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. Implementieren Sie die AugmentQuickInfoSession-Methode. In diesem Beispiel findet die Methode das aktuelle Wort oder das vorherige Wort, wenn sich der Cursor am Ende einer Zeile oder eines Textpuffers befindet. Wenn das Wort einer der Methodennamen ist, wird die Beschreibung für diesen Methodennamen dem QuickInfo-Inhalt hinzugefügt.

    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. Außerdem müssen Sie eine Dispose()-Methode implementieren, da IQuickInfoSource folgendes implementiert wird IDisposable:

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

Implementieren eines QuickInfo-Quellanbieters

Der Anbieter der QuickInfo-Quelle dient hauptsächlich dazu, sich als MEF-Komponententeil zu exportieren und die QuickInfo-Quelle zu instanziieren. Da es sich um eine MEF-Komponente ist, kann sie andere MEF-Komponententeile importieren.

So implementieren Sie einen QuickInfo-Quellanbieter

  1. Deklarieren Sie einen QuickInfo-Quellanbieter namens TestQuickInfoSourceProvider , der ihn implementiert IQuickInfoSourceProvider, und exportieren Sie ihn mit einer NameAttribute "QuickInfo-Quelle", einer OrderAttribute von "Before="default" und einem ContentTypeAttribute "Text".

    [Export(typeof(IQuickInfoSourceProvider))]
    [Name("ToolTip QuickInfo Source")]
    [Order(Before = "Default Quick Info Presenter")]
    [ContentType("text")]
    internal class TestQuickInfoSourceProvider : IQuickInfoSourceProvider
    
  2. Importieren Sie zwei Editordienste ITextStructureNavigatorSelectorService und ITextBufferFactoryService, als Eigenschaften von TestQuickInfoSourceProvider.

    [Import]
    internal ITextStructureNavigatorSelectorService NavigatorService { get; set; }
    
    [Import]
    internal ITextBufferFactoryService TextBufferFactoryService { get; set; }
    
  3. Implementieren TryCreateQuickInfoSource , um ein neues TestQuickInfoSourcezurückzugeben.

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

Implementieren eines QuickInfo-Controllers

QuickInfo-Controller bestimmen, wann QuickInfo angezeigt wird. In diesem Beispiel wird QuickInfo angezeigt, wenn sich der Zeiger über einem Wort befindet, das einem der Methodennamen entspricht. Der QuickInfo-Controller implementiert einen Mauszeigerereignishandler, der eine QuickInfo-Sitzung auslöst.

So implementieren Sie einen QuickInfo-Controller

  1. Deklarieren Sie eine Klasse, die sie implementiert IIntellisenseController, und nennen Sie sie TestQuickInfoController.

    internal class TestQuickInfoController : IIntellisenseController
    
  2. Fügen Sie private Felder für die Textansicht, die in der Textansicht dargestellten Textpuffer, die QuickInfo-Sitzung und den QuickInfo-Controlleranbieter hinzu.

    private ITextView m_textView;
    private IList<ITextBuffer> m_subjectBuffers;
    private TestQuickInfoControllerProvider m_provider;
    private IQuickInfoSession m_session;
    
  3. Fügen Sie einen Konstruktor hinzu, der die Felder festlegt, und fügt den Mauszeigerereignishandler hinzu.

    internal TestQuickInfoController(ITextView textView, IList<ITextBuffer> subjectBuffers, TestQuickInfoControllerProvider provider)
    {
        m_textView = textView;
        m_subjectBuffers = subjectBuffers;
        m_provider = provider;
    
        m_textView.MouseHover += this.OnTextViewMouseHover;
    }
    
  4. Fügen Sie den Mauszeigerereignishandler hinzu, der die QuickInfo-Sitzung auslöst.

    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. Implementieren Sie die Detach Methode, damit der Mauszeigerereignishandler entfernt wird, wenn der Controller von der Textansicht getrennt wird.

    public void Detach(ITextView textView)
    {
        if (m_textView == textView)
        {
            m_textView.MouseHover -= this.OnTextViewMouseHover;
            m_textView = null;
        }
    }
    
  6. Implementieren Sie die ConnectSubjectBuffer Methode und die DisconnectSubjectBuffer Methode als leere Methoden für dieses Beispiel.

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

Implementieren des QuickInfo-Controlleranbieters

Der Anbieter des QuickInfo-Controllers dient hauptsächlich dazu, sich als MEF-Komponententeil zu exportieren und den QuickInfo-Controller zu instanziieren. Da es sich um eine MEF-Komponente ist, kann sie andere MEF-Komponententeile importieren.

So implementieren Sie den QuickInfo-Controlleranbieter

  1. Deklarieren Sie eine Klasse mit dem Namen TestQuickInfoControllerProvider , die sie implementiert IIntellisenseControllerProvider, und exportieren Sie sie mit einem NameAttribute "QuickInfo-Controller für QuickInfo" und einem ContentTypeAttribute "Text":

    [Export(typeof(IIntellisenseControllerProvider))]
    [Name("ToolTip QuickInfo Controller")]
    [ContentType("text")]
    internal class TestQuickInfoControllerProvider : IIntellisenseControllerProvider
    
  2. Importieren Sie IQuickInfoBroker als Eigenschaft.

    [Import]
    internal IQuickInfoBroker QuickInfoBroker { get; set; }
    
  3. Implementieren Sie die TryCreateIntellisenseController Methode, indem Sie den QuickInfo-Controller instanziieren.

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

Erstellen und Testen des Codes

Um diesen Code zu testen, erstellen Sie die QuickInfoTest-Lösung, und führen Sie sie in der experimentellen Instanz aus.

So erstellen und testen Sie die QuickInfoTest-Lösung

  1. Erstellen Sie die Projektmappe.

  2. Wenn Sie dieses Projekt im Debugger ausführen, wird eine zweite Instanz von Visual Studio gestartet.

  3. Erstellen Sie eine Textdatei, und geben Sie Text ein, der die Wörter "add" und "subtrahiert" enthält.

  4. Bewegen Sie den Mauszeiger über eines der Vorkommen von "add". Die Signatur und die Beschreibung der add Methode sollten angezeigt werden.