Sdílet prostřednictvím


Návod: Zobrazení popisů rychlých informací

QuickInfo je funkce IntelliSense, která zobrazuje podpisy a popisy metod, když uživatel přesune ukazatel na název metody. Funkce založené na jazyce, jako je QuickInfo, můžete implementovat tak, že definujete identifikátory, pro které chcete zadat popisy Rychlých informací, a pak vytvoříte popis, ve kterém se má obsah zobrazit. QuickInfo můžete definovat v kontextu služby jazyka, nebo můžete definovat vlastní příponu názvu souboru a typ obsahu a zobrazit QuickInfo pouze pro tento typ, nebo můžete QuickInfo zobrazit pro existující typ obsahu (například "text"). Tento návod ukazuje, jak zobrazit QuickInfo pro typ obsahu "text".

Příklad Rychlé informace v tomto návodu zobrazí popisy, když uživatel přesune ukazatel na název metody. Tento návrh vyžaduje implementaci těchto čtyř rozhraní:

  • zdrojové rozhraní

  • rozhraní zprostředkovatele zdroje

  • rozhraní kontroleru

  • rozhraní zprostředkovatele kontroleru

    Poskytovatelé zdrojového a kontroleru jsou součástí komponenty MEF (Managed Extensibility Framework) a zodpovídají za export tříd zdrojového a kontroleru a import služeb a zprostředkovatelů, jako je například ITextBufferFactoryService, která vytvoří vyrovnávací paměť textu popisu a IQuickInfoBroker, která aktivuje relaci QuickInfo.

    V tomto příkladu zdroj QuickInfo používá pevně zakódovaný seznam názvů a popisů metod, ale v úplných implementacích zodpovídá za poskytování tohoto obsahu služba jazyka a dokumentace jazyka.

Vytvoření projektu MEF

Vytvoření projektu MEF

  1. Vytvořte projekt VSIX jazyka C#. (V Dialogové okno Nový projekt , vyberte Visual C# / Rozšiřitelnost a pak projekt VSIX.) Pojmenujte řešení QuickInfoTest.

  2. Přidejte do projektu šablonu položky klasifikátoru editoru. Další informace najdete v tématu Vytvoření rozšíření pomocí šablony položky editoru.

  3. Odstraňte existující soubory třídy.

Implementace zdroje QuickInfo

Zdroj QuickInfo zodpovídá za shromažďování sady identifikátorů a jejich popisů a přidání obsahu do vyrovnávací paměti textu popisu, když dojde k výskytu některého z identifikátorů. V tomto příkladu se identifikátory a jejich popisy právě přidají do zdrojového konstruktoru.

Implementace zdroje QuickInfo

  1. Přidejte soubor třídy a pojmenujte ho TestQuickInfoSource.

  2. Přidejte odkaz na Microsoft.VisualStudio.Language.IntelliSense.

  3. Přidejte následující importy.

    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. Deklarujte třídu, která implementuje IQuickInfoSource, a pojmenujte ji TestQuickInfoSource.

    internal class TestQuickInfoSource : IQuickInfoSource
    
  5. Přidejte pole pro zprostředkovatele zdroje QuickInfo, vyrovnávací paměť textu a sadu názvů metod a podpisů metod. V tomto příkladu jsou názvy metod a podpisy inicializovány v konstruktoru TestQuickInfoSource .

    private TestQuickInfoSourceProvider m_provider;
    private ITextBuffer m_subjectBuffer;
    private Dictionary<string, string> m_dictionary;
    
  6. Přidejte konstruktor, který nastaví zprostředkovatele zdroje QuickInfo a textové vyrovnávací paměti a naplní sadu názvů metod a podpisy a popisy metody.

    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. Implementujte metodu AugmentQuickInfoSession . V tomto příkladu metoda najde aktuální slovo nebo předchozí slovo, pokud je kurzor na konci řádku nebo textové vyrovnávací paměti. Pokud je slovo jedním z názvů metod, popis pro tento název metody se přidá do obsahu 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. Musíte také implementovat Metodu Dispose(), protože IQuickInfoSource implementuje IDisposable:

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

Implementace zprostředkovatele zdroje QuickInfo

Zprostředkovatel zdroje QuickInfo slouží především k exportu jako součásti MEF a vytvoření instance zdroje QuickInfo. Protože se jedná o součást komponenty MEF, může importovat další součásti MEF.

Implementace zprostředkovatele zdroje QuickInfo

  1. Deklarujte zprostředkovatele zdroje QuickInfo s názvem TestQuickInfoSourceProvider , který implementuje IQuickInfoSourceProvider, a exportujte ho pomocí NameAttribute "ToolTip QuickInfo Source", an OrderAttribute of Before="default" a ContentTypeAttribute "text".

    [Export(typeof(IQuickInfoSourceProvider))]
    [Name("ToolTip QuickInfo Source")]
    [Order(Before = "Default Quick Info Presenter")]
    [ContentType("text")]
    internal class TestQuickInfoSourceProvider : IQuickInfoSourceProvider
    
  2. Naimportujte dvě služby ITextStructureNavigatorSelectorService editoru a ITextBufferFactoryServicejako vlastnosti TestQuickInfoSourceProvider.

    [Import]
    internal ITextStructureNavigatorSelectorService NavigatorService { get; set; }
    
    [Import]
    internal ITextBufferFactoryService TextBufferFactoryService { get; set; }
    
  3. Implementujte TryCreateQuickInfoSource pro vrácení nového TestQuickInfoSource.

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

Implementace kontroleru QuickInfo

Kontrolery QuickInfo určují, kdy se zobrazí QuickInfo. V tomto příkladu se QuickInfo zobrazí, když je ukazatel nad slovem, které odpovídá jednomu z názvů metod. Kontroler QuickInfo implementuje obslužnou rutinu události najetí myší, která aktivuje relaci QuickInfo.

Implementace kontroleru QuickInfo

  1. Deklarujte třídu, která implementuje IIntellisenseController, a pojmenujte ji TestQuickInfoController.

    internal class TestQuickInfoController : IIntellisenseController
    
  2. Přidejte soukromá pole pro textové zobrazení, vyrovnávací paměti textu reprezentované v textovém zobrazení, relaci QuickInfo a zprostředkovatele kontroleru QuickInfo.

    private ITextView m_textView;
    private IList<ITextBuffer> m_subjectBuffers;
    private TestQuickInfoControllerProvider m_provider;
    private IQuickInfoSession m_session;
    
  3. Přidejte konstruktor, který nastaví pole a přidá obslužnou rutinu události najetí myší.

    internal TestQuickInfoController(ITextView textView, IList<ITextBuffer> subjectBuffers, TestQuickInfoControllerProvider provider)
    {
        m_textView = textView;
        m_subjectBuffers = subjectBuffers;
        m_provider = provider;
    
        m_textView.MouseHover += this.OnTextViewMouseHover;
    }
    
  4. Přidejte obslužnou rutinu události najetí myší, která aktivuje relaci 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. Implementujte metodu Detach tak, aby odebral obslužnou rutinu události najetí myší při odpojení kontroleru z textového zobrazení.

    public void Detach(ITextView textView)
    {
        if (m_textView == textView)
        {
            m_textView.MouseHover -= this.OnTextViewMouseHover;
            m_textView = null;
        }
    }
    
  6. Implementujte metodu a metodu ConnectSubjectBuffer DisconnectSubjectBuffer jako prázdné metody pro tento příklad.

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

Implementace zprostředkovatele kontroleru QuickInfo

Zprostředkovatel kontroleru QuickInfo slouží primárně k exportu jako součásti MEF a vytvoření instance kontroleru QuickInfo. Protože se jedná o součást komponenty MEF, může importovat další součásti MEF.

Implementace zprostředkovatele kontroleru QuickInfo

  1. Deklarujte třídu s názvem TestQuickInfoControllerProvider , která implementuje IIntellisenseControllerProvider, a exportujte ji pomocí NameAttribute "ToolTip QuickInfo Controller" a ContentTypeAttribute "text":

    [Export(typeof(IIntellisenseControllerProvider))]
    [Name("ToolTip QuickInfo Controller")]
    [ContentType("text")]
    internal class TestQuickInfoControllerProvider : IIntellisenseControllerProvider
    
  2. Importujte vlastnost IQuickInfoBroker jako vlastnost.

    [Import]
    internal IQuickInfoBroker QuickInfoBroker { get; set; }
    
  3. Implementujte metodu TryCreateIntellisenseController vytvořením instance kontroleru QuickInfo.

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

Sestavení a otestování kódu

Tento kód otestujete tak, že sestavíte řešení QuickInfoTest a spustíte ho v experimentální instanci.

Sestavení a testování řešení QuickInfoTest

  1. Sestavte řešení.

  2. Když tento projekt spustíte v ladicím programu, spustí se druhá instance sady Visual Studio.

  3. Vytvořte textový soubor a zadejte nějaký text, který obsahuje slova "sčítání" a "odečíst".

  4. Přesuňte ukazatel myši na jeden z výskytů příkazu "add". Měl by se zobrazit podpis a popis add metody.