Freigeben über


Exemplarische Vorgehensweise: QuickInfo-QuickInfo anzeigen

IntelliSense-Feature eine QuickInfo mit Methodensignaturen und Beschreibungen angezeigt wird, wenn ein Benutzer den Mauszeiger über einem Methodennamen gezeigt wird. Sie können LANGUAGE-basierte Funktionen wie QuickInfos implementieren, indem Sie die ID definieren, für die Sie die Beschreibungen der QuickInfo bereitstellen möchten, und dann eine QuickInfo erstellen, in der der Inhalt angezeigt wird. Sie können die QuickInfo im Kontext eines Sprachdiensts definieren, oder Sie können definieren, Erweiterung und Inhaltstyp besitzen und die QuickInfo nur für diesen Typ anzuzeigen, oder Sie können einen vorhandenen Inhaltstyp für QuickInfos angezeigt werden (z. B. „text“). In dieser exemplarischen Vorgehensweise wird erläutert, wie Sie QuickInfos für den Inhaltstyp „text“ anzeigt.

Das Beispiel für eine QuickInfo in dieser exemplarischen Vorgehensweise werden die QuickInfo angezeigt, wenn ein Benutzer den Mauszeiger über einem Methodennamen gezeigt wird. Dieser Entwurf müssen Sie diese vier Schnittstellen zu implementieren:

  • Quellschnittstelle

  • Quellanbieter Oberfläche

  • Controller-Schnittstelle

  • Controller-Anbieter Oberfläche

Die Quell- und Controller-Anbieter sind Komponenten des Managed Extensibility Framework (MEF) und zum Exportieren der Quell- und Controllerklassen und das Importieren von Diensten und Brokern wie ITextBufferFactoryService, der den QuickInfo-Text Puffer zuständig erstellt, und IQuickInfoBroker, das die QuickInfo-Sitzung gestartet wird.

In diesem Beispiel wird die QuickInfo Quelle wird eine hartcodierte Liste von Methodennamen und Beschreibungen, aber in den vollständigen Implementierungen, sind der Sprachdienst und in der Dokumentation zur Sprache zum Bereitstellen dieses Inhalts verantwortlich.

Vorbereitungsmaßnahmen

Zum Abschließen dieser exemplarischen Vorgehensweise müssen Sie Visual Studio 2010 SDKinstallieren.

Hinweis

Weitere Informationen über das Visual Studio-SDK finden Sie unter Erweitern von Visual Studio Overview.Um herauszufinden finden Sie unter wie das Visual Studio-SDK, auf Visual Studio Extensibility Developer Center der MSDN-Website herunterlädt.

Ein MEF-Projekt erstellen

So erstellen Sie ein MEF-Projekt

  1. Erstellen Sie ein Projekt Editor-Klassifizierungs. Geben Sie der Projektmappe QuickInfoTest.

  2. Öffnen Sie die Source.extension.vsixmanifest-Datei im VSIX-Manifest-Editor.

  3. Überprüfen Sie, ob die Content Überschrift einen MEF-Komponenten-Inhaltstyp enthält und dass Path zu QuickInfoTest.dll festgelegt ist.

  4. Speichern und schließen Sie Source.extension.vsixmanifest.

  5. Fügen Sie den folgenden Verweis auf das Projekt, und falsefestlegen CopyLocal hinzu:

    Microsoft.VisualStudio.Language.Intellisense

  6. Löschen Sie die vorhandenen Klassendateien.

Die QuickInfo-Quelle implementieren

Die QuickInfo Quelle ist zum Erfassen des Satzes der Bezeichner und ihren Beschreibungen und zum Hinzufügen von Inhalt in den QuickInfo-Text Puffer zuständig, wenn einer der Bezeichner gefunden wird. In diesem Beispiel werden die ID und ihre Beschreibungen aktuell im Konstruktor Quelle hinzugefügt.

So implementieren Sie die Quelle der QuickInfo

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

  2. Fügen Sie die folgenden Importe hinzu.

    Imports System
    Imports System.Collections.Generic
    Imports System.Linq
    Imports System.Text
    Imports System.Collections.ObjectModel
    Imports System.ComponentModel.Composition
    Imports Microsoft.VisualStudio.Language.Intellisense
    Imports Microsoft.VisualStudio.Text
    Imports Microsoft.VisualStudio.Text.Editor
    Imports Microsoft.VisualStudio.Text.Operations
    Imports Microsoft.VisualStudio.Text.Tagging
    Imports Microsoft.VisualStudio.Utilities
    
    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;
    
  3. Deklarieren Sie eine Klasse, die IQuickInfoSourceimplementiert, und nennen Sie sie TestQuickInfoSource.

    Friend Class TestQuickInfoSource
        Implements IQuickInfoSource
    
    internal class TestQuickInfoSource : IQuickInfoSource
    
  4. Fügen Sie Felder für den QuickInfos quellanbieter, den Textpuffer und einen Satz von Methodensignaturen und Methodennamen hinzu. In diesem Beispiel werden die Methodennamen und -unterzeichnungen im TestQuickInfoSource-Konstruktor initialisiert.

    Private m_provider As TestQuickInfoSourceProvider
    Private m_subjectBuffer As ITextBuffer
    Private m_dictionary As Dictionary(Of String, String)
    
    private TestQuickInfoSourceProvider m_provider;
    private ITextBuffer m_subjectBuffer;
    private Dictionary<string, string> m_dictionary;
    
  5. Fügen Sie einen Konstruktor, der die QuickInfo quellanbieter und den Textpuffer festgelegt wird, und füllt den Satz von Methodennamen und Methodensignaturen und Beschreibungen auf.

    Public Sub New(ByVal provider As TestQuickInfoSourceProvider, ByVal subjectBuffer As ITextBuffer)
        m_provider = provider
        m_subjectBuffer = subjectBuffer
    
        'these are the method names and their descriptions
        m_dictionary = New Dictionary(Of String, String)()
        m_dictionary.Add("add", "int add(int firstInt, int secondInt)" & vbLf & "Adds one integer to another.")
        m_dictionary.Add("subtract", "int subtract(int firstInt, int secondInt)" & vbLf & "Subtracts one integer from another.")
        m_dictionary.Add("multiply", "int multiply(int firstInt, int secondInt)" & vbLf & "Multiplies one integer by another.")
        m_dictionary.Add("divide", "int divide(int firstInt, int secondInt)" & vbLf & "Divides one integer by another.")
    End Sub
    
    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.");
    }
    
  6. Implementieren Sie die AugmentQuickInfoSession-Methode. In diesem Beispiel findet die Methode das aktuelle Wort oder das vorhergehende Wort, wenn der Cursor sich am Ende einer Linie oder des Textpuffers ist. Wenn das Wort einer der Methodenname ist, wird die Beschreibung für den Methodennamen für den QuickInfo-Inhalt hinzugefügt.

    Public Sub AugmentQuickInfoSession(ByVal session As IQuickInfoSession, ByVal qiContent As IList(Of Object), ByRef applicableToSpan As ITrackingSpan) Implements IQuickInfoSource.AugmentQuickInfoSession
        ' Map the trigger point down to our buffer. 
        Dim subjectTriggerPoint As System.Nullable(Of SnapshotPoint) = session.GetTriggerPoint(m_subjectBuffer.CurrentSnapshot)
        If Not subjectTriggerPoint.HasValue Then
            applicableToSpan = Nothing 
            Exit Sub 
        End If 
    
        Dim currentSnapshot As ITextSnapshot = subjectTriggerPoint.Value.Snapshot
        Dim querySpan As New SnapshotSpan(subjectTriggerPoint.Value, 0)
    
        'look for occurrences of our QuickInfo words in the span 
        Dim navigator As ITextStructureNavigator = m_provider.NavigatorService.GetTextStructureNavigator(m_subjectBuffer)
        Dim extent As TextExtent = navigator.GetExtentOfWord(subjectTriggerPoint.Value)
        Dim searchText As String = extent.Span.GetText()
    
        For Each key As String In m_dictionary.Keys
            Dim foundIndex As Integer = searchText.IndexOf(key, StringComparison.CurrentCultureIgnoreCase)
            If foundIndex > -1 Then
                applicableToSpan = currentSnapshot.CreateTrackingSpan(querySpan.Start.Add(foundIndex).Position, 9, SpanTrackingMode.EdgeInclusive)
    
                Dim value As String = ""
                m_dictionary.TryGetValue(key, value)
                If value IsNot Nothing Then
                    qiContent.Add(value)
                Else
                    qiContent.Add("")
                End If 
    
                Exit Sub 
            End If 
        Next
    
        applicableToSpan = Nothing 
    End Sub
    
    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
                    );
    
                string value;
                m_dictionary.TryGetValue(key, out value);
                if (value != null)
                    qiContent.Add(value);
                else
                    qiContent.Add("");
    
                return;
            }
        }
    
        applicableToSpan = null;
    }
    
  7. Sie müssen eine Dispose()- Methode implementieren, da IQuickInfoSourceIDisposableimplementiert:

    Private m_isDisposed As Boolean 
    Public Sub Dispose() Implements IDisposable.Dispose
        If Not m_isDisposed Then
            GC.SuppressFinalize(Me)
            m_isDisposed = True 
        End If 
    End Sub
    
    private bool m_isDisposed;
    public void Dispose()
    {
        if (!m_isDisposed)
        {
            GC.SuppressFinalize(this);
            m_isDisposed = true;
        }
    }
    

Implementieren eines QuickInfo-Quellanbieter

Der Anbieter der QuickInfo als Quelle dient hauptsächlich zur Teilnahme MEF-Komponenten-Teil zu exportieren und die QuickInfo Quelle zu instanziieren. Da es sich um ein MEF-Komponenten-Teil ist, kann er anderen MEF-Komponenten-Teile importieren.

So fügen Sie eine QuickInfo quellanbieter implementieren

  1. Deklarieren Sie eine QuickInfo mit dem Namen quellanbieter TestQuickInfoSourceProvider , der IQuickInfoSourceProviderimplementiert, und exportieren Sie ihn mit NameAttribute „,“ QuickInfo-QuickInfo-Quelle der OrderAttribute von Before= " default“ und ContentTypeAttribute „Text“.

    <Export(GetType(IQuickInfoSourceProvider))> _
    <Name("ToolTip QuickInfo Source")> _
    <Order(Before:=" Default Quick Info Presenter")> _
    <ContentType("text")> _
    Friend Class TestQuickInfoSourceProvider
        Implements IQuickInfoSourceProvider
    
    [Export(typeof(IQuickInfoSourceProvider))]
    [Name("ToolTip QuickInfo Source")]
    [Order(Before = "Default Quick Info Presenter")]
    [ContentType("text")]
    internal class TestQuickInfoSourceProvider : IQuickInfoSourceProvider
    
  2. Importieren Sie zwei Editor Dienste, ITextStructureNavigatorSelectorService und ITextBufferFactoryService, als Eigenschaften von TestQuickInfoSourceProvider.

    Private _NavigatorService As ITextStructureNavigatorSelectorService
    <Import()> _
    Friend Property NavigatorService() As ITextStructureNavigatorSelectorService
        Get 
            Return _NavigatorService
        End Get 
        Set(ByVal value As ITextStructureNavigatorSelectorService)
            _NavigatorService = value
        End Set 
    End Property 
    
    Private _TextBufferFactoryService As ITextBufferFactoryService
    <Import()> _
    Friend Property TextBufferFactoryService() As ITextBufferFactoryService
        Get 
            Return _TextBufferFactoryService
        End Get 
        Set(ByVal value As ITextBufferFactoryService)
            _TextBufferFactoryService = value
        End Set 
    End Property
    
    [Import]
    internal ITextStructureNavigatorSelectorService NavigatorService { get; set; }
    
    [Import]
    internal ITextBufferFactoryService TextBufferFactoryService { get; set; }
    
  3. Implementieren Sie TryCreateQuickInfoSource , um ein neues TestQuickInfoSourcezurückzugeben.

    Public Function TryCreateQuickInfoSource(ByVal textBuffer As ITextBuffer) As IQuickInfoSource Implements IQuickInfoSourceProvider.TryCreateQuickInfoSource
        Return New TestQuickInfoSource(Me, textBuffer)
    End Function
    
    public IQuickInfoSource TryCreateQuickInfoSource(ITextBuffer textBuffer)
    {
        return new TestQuickInfoSource(this, textBuffer);
    }
    

Implementieren eines QuickInfo-Controller

controller QuickInfo bestimmen, wann QuickInfo angezeigt werden soll. In diesem Beispiel wird ein QuickInfo angezeigt, wenn der Mauszeiger über dem Wort handelt, die eine Verbindung mit einem Methodennamen entsprechen. Die QuickInfo Mauszeigerbewegungs controller implementiert einen Ereignishandler, der eine QuickInfo-Sitzung gestartet wird.

So fügen Sie eine QuickInfo controller implementieren

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

    Friend Class TestQuickInfoController
        Implements IIntellisenseController
    
    internal class TestQuickInfoController : IIntellisenseController
    
  2. Fügen Sie private Felder für die Textansicht, die Textpuffer, die in der Textansicht dargestellt werden, die controller-Anbieter QuickInfo-Sitzung und QuickInfos hinzu.

    Private m_textView As ITextView
    Private m_subjectBuffers As IList(Of ITextBuffer)
    Private m_provider As TestQuickInfoControllerProvider
    Private m_session As IQuickInfoSession
    
    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 festlegen und den Ereignishandler Mauszeigerbewegungs hinzugefügt wird.

    Friend Sub New(ByVal textView As ITextView, ByVal subjectBuffers As IList(Of ITextBuffer), ByVal provider As TestQuickInfoControllerProvider)
        m_textView = textView
        m_subjectBuffers = subjectBuffers
        m_provider = provider
    
        AddHandler m_textView.MouseHover, AddressOf Me.OnTextViewMouseHover
    End Sub
    
    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 Ereignishandler hinzu, der die Mauszeigerbewegungs QuickInfo-Sitzung gestartet wird.

    Private Sub OnTextViewMouseHover(ByVal sender As Object, ByVal e As MouseHoverEventArgs)
        'find the mouse position by mapping down to the subject buffer 
        Dim point As System.Nullable(Of SnapshotPoint) = m_textView.BufferGraph.MapDownToFirstMatch(New SnapshotPoint(m_textView.TextSnapshot, e.Position), PointTrackingMode.Positive, Function(snapshot) m_subjectBuffers.Contains(snapshot.TextBuffer), PositionAffinity.Predecessor)
    
        If point IsNot Nothing Then 
            Dim triggerPoint As ITrackingPoint = point.Value.Snapshot.CreateTrackingPoint(point.Value.Position, PointTrackingMode.Positive)
    
            If Not m_provider.QuickInfoBroker.IsQuickInfoActive(m_textView) Then
                m_session = m_provider.QuickInfoBroker.TriggerQuickInfo(m_textView, triggerPoint, True)
            End If 
        End If 
    End Sub
    
    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, sodass sie den Mauszeigerbewegungs Ereignishandler entfernt, wenn der Controller von der Textansicht getrennt wird.

    Public Sub Detach(ByVal textView As ITextView) Implements IIntellisenseController.Detach
        If m_textView Is textView Then 
            AddHandler m_textView.MouseHover, AddressOf Me.OnTextViewMouseHover
            m_textView = Nothing 
        End If 
    End Sub
    
    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 Methode für dieses Beispiel.

    Public Sub ConnectSubjectBuffer(ByVal subjectBuffer As ITextBuffer) Implements IIntellisenseController.ConnectSubjectBuffer
    
    End Sub 
    
    Public Sub DisconnectSubjectBuffer(ByVal subjectBuffer As ITextBuffer) Implements IIntellisenseController.DisconnectSubjectBuffer
    
    End Sub
    
    public void ConnectSubjectBuffer(ITextBuffer subjectBuffer)
    {
    }
    
    public void DisconnectSubjectBuffer(ITextBuffer subjectBuffer)
    {
    }
    

Implementieren des QuickInfo-Controller-Anbieter

Der Anbieter controllers dient hauptsächlich der QuickInfo selbst als MEF-Komponenten-Teil zu exportieren und QuickInfos controller zu instanziieren. Da es sich um ein MEF-Komponenten-Teil ist, kann er anderen MEF-Komponenten-Teile importieren.

So implementieren controller-Anbieter QuickInfo

  1. Deklarieren Sie eine Klasse mit dem Namen TestQuickInfoControllerProvider , die IIntellisenseControllerProviderimplementiert, und exportieren Sie sie mit NameAttribute „des QuickInfo-QuickInfo-Controllers“ und“ Text „ ContentTypeAttribute :

    <Export(GetType(IIntellisenseControllerProvider))> _
    <Name("ToolTip QuickInfo Controller")> _
    <ContentType("text")> _
    Friend Class TestQuickInfoControllerProvider
        Implements IIntellisenseControllerProvider
    
    [Export(typeof(IIntellisenseControllerProvider))]
    [Name("ToolTip QuickInfo Controller")]
    [ContentType("text")]
    internal class TestQuickInfoControllerProvider : IIntellisenseControllerProvider
    
  2. Importieren Sie IQuickInfoBroker als Eigenschaft.

    Private _QuickInfoBroker As IQuickInfoBroker
    <Import()> _
    Friend Property QuickInfoBroker() As IQuickInfoBroker
        Get 
            Return _QuickInfoBroker
        End Get 
        Set(ByVal value As IQuickInfoBroker)
            _QuickInfoBroker = value
        End Set 
    End Property
    
    [Import]
    internal IQuickInfoBroker QuickInfoBroker { get; set; }
    
  3. Implementieren Sie die TryCreateIntellisenseController-Methode, indem Sie den QuickInfos controller instanziieren.

    Public Function TryCreateIntellisenseController(ByVal textView As ITextView, ByVal subjectBuffers As IList(Of ITextBuffer)) As IIntellisenseController Implements IIntellisenseControllerProvider.TryCreateIntellisenseController
        Return New TestQuickInfoController(textView, subjectBuffers, Me)
    End Function
    
    public IIntellisenseController TryCreateIntellisenseController(ITextView textView, IList<ITextBuffer> subjectBuffers)
    {
        return new TestQuickInfoController(textView, subjectBuffers, this);
    }
    

Erstellen und Testen von Code

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

So erstellen und testen die QuickInfoTest-Projektmappe

  1. Erstellen Sie die Projektmappe.

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

  3. Erstellen Sie eine Textdatei, und geben Sie Text ein, der die Wörter „Hinzufügen“ „beinhaltet und subtrahieren Sie im Abschnitt“.

  4. Bewegen Sie den Mauszeiger über einem der Vorkommen von „Hinzufügen“. Die Signatur und die Beschreibung der add-Methode sollte angezeigt werden.

Siehe auch

Aufgaben

Exemplarische Vorgehensweise: Verknüpfen einer Dateinamenerweiterung eines Inhaltstyps