İzlenecek yol: QuickInfo araç ipuçlarını görüntüleme

QuickInfo, kullanıcı işaretçiyi bir yöntem adının üzerine getirince yöntem imzalarını ve açıklamalarını görüntüleyen bir IntelliSense özelliğidir. QuickInfo açıklamalarını sağlamak istediğiniz tanımlayıcıları tanımlayarak ve ardından içeriğin görüntüleneceği bir araç ipucu oluşturarak QuickInfo gibi dil tabanlı özellikleri uygulayabilirsiniz. QuickInfo'yu bir dil hizmeti bağlamında tanımlayabilir veya kendi dosya adı uzantınızı ve içerik türünüzü tanımlayıp yalnızca bu tür için QuickInfo'yu görüntüleyebilir veya mevcut bir içerik türü için QuickInfo'yu ("metin" gibi) görüntüleyebilirsiniz. Bu izlenecek yol, "metin" içerik türü için QuickInfo'nun nasıl görüntüleneceğini gösterir.

Bu kılavuzdaki QuickInfo örneği, bir kullanıcı işaretçiyi bir yöntem adının üzerine getirince araç ipuçlarını görüntüler. Bu tasarım için şu dört arabirimi uygulamanız gerekir:

  • kaynak arabirimi

  • kaynak sağlayıcı arabirimi

  • denetleyici arabirimi

  • denetleyici sağlayıcı arabirimi

    Kaynak ve denetleyici sağlayıcıları Yönetilen Genişletilebilirlik Çerçevesi (MEF) bileşen parçalarıdır ve kaynak ve denetleyici sınıflarını dışarı aktarmaktan ve araç ipucu metin arabelleği oluşturan gibi hizmetleri ve IQuickInfoBrokeraracıları ITextBufferFactoryServiceve QuickInfo oturumunu tetikleyen aracıları içeri aktarmaktan sorumludur.

    Bu örnekte, QuickInfo kaynağı yöntem adlarının ve açıklamalarının sabit kodlanmış bir listesini kullanır, ancak tam uygulamalarda, dil hizmeti ve dil belgeleri bu içeriği sağlamaktan sorumludur.

MEF projesi oluşturma

MEF projesi oluşturmak için

  1. C# VSIX projesi oluşturun. (Yeni Proje iletişim kutusu, Visual C# / Genişletilebilirlik'i ve ardından VSIX Projesi'ni seçin.) Çözümü QuickInfoTestolarak adlandırın.

  2. Projeye bir Düzenleyici Sınıflandırıcısı öğesi şablonu ekleyin. Daha fazla bilgi için bkz . Düzenleyici öğesi şablonuyla uzantı oluşturma.

  3. Varolan sınıf dosyalarını silin.

QuickInfo kaynağını uygulama

Tanımlayıcılardan biriyle karşılaşıldığında QuickInfo kaynağı, tanımlayıcı kümesini ve açıklamalarını toplamaktan ve içeriği araç ipucu metin arabelleğine eklemekle sorumludur. Bu örnekte, tanımlayıcılar ve açıklamaları kaynak oluşturucuya yeni eklenir.

QuickInfo kaynağını uygulamak için

  1. Bir sınıf dosyası ekleyin ve adını verin TestQuickInfoSource.

  2. Microsoft.VisualStudio.Language.IntelliSense'e bir başvuru ekleyin.

  3. Aşağıdaki içeri aktarmaları ekleyin.

    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. uygulayan IQuickInfoSourcebir sınıf bildirin ve adını verin TestQuickInfoSource.

    internal class TestQuickInfoSource : IQuickInfoSource
    
  5. QuickInfo kaynak sağlayıcısı, metin arabelleği ve yöntem adları ve yöntem imzaları kümesi için alanlar ekleyin. Bu örnekte, yöntem adları ve imzaları oluşturucuda TestQuickInfoSource başlatılır.

    private TestQuickInfoSourceProvider m_provider;
    private ITextBuffer m_subjectBuffer;
    private Dictionary<string, string> m_dictionary;
    
  6. QuickInfo kaynak sağlayıcısını ve metin arabelleği ayarlayan ve yöntem adları kümesini, yöntem imzalarını ve açıklamalarını dolduran bir oluşturucu ekleyin.

    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. AugmentQuickInfoSession yöntemini uygulayın. Bu örnekte, imleç bir satırın veya metin arabelleğinin sonundaysa yöntem geçerli sözcüğü veya önceki sözcüğü bulur. Sözcük yöntem adlarından biriyse, bu yöntem adının açıklaması QuickInfo içeriğine eklenir.

    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. Şunu uyguladığından IQuickInfoSource dispose() yöntemi de uygulamanız IDisposablegerekir:

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

QuickInfo kaynak sağlayıcısı uygulama

QuickInfo kaynağının sağlayıcısı öncelikle kendisini bir MEF bileşeni parçası olarak dışarı aktarmaya ve QuickInfo kaynağının örneğini oluşturmaya hizmet eder. Bu bir MEF bileşeni parçası olduğundan, diğer MEF bileşen parçalarını içeri aktarabilir.

QuickInfo kaynak sağlayıcısı uygulamak için

  1. uygulayan adlı TestQuickInfoSourceProvider bir QuickInfo kaynak sağlayıcısı bildirin ve bunu NameAttribute "ToolTip QuickInfo Kaynağı", OrderAttribute Before="default" ve "ContentTypeAttributetext" ile dışarı aktarınIQuickInfoSourceProvider.

    [Export(typeof(IQuickInfoSourceProvider))]
    [Name("ToolTip QuickInfo Source")]
    [Order(Before = "Default Quick Info Presenter")]
    [ContentType("text")]
    internal class TestQuickInfoSourceProvider : IQuickInfoSourceProvider
    
  2. İki düzenleyici hizmetini ITextStructureNavigatorSelectorService ve ITextBufferFactoryServiceözelliklerini içeri aktarın TestQuickInfoSourceProvider.

    [Import]
    internal ITextStructureNavigatorSelectorService NavigatorService { get; set; }
    
    [Import]
    internal ITextBufferFactoryService TextBufferFactoryService { get; set; }
    
  3. Yeni TestQuickInfoSourcebir döndürmek için uygulayınTryCreateQuickInfoSource.

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

QuickInfo denetleyicisi uygulama

QuickInfo denetleyicileri QuickInfo'nun ne zaman görüntüleneceğini belirler. Bu örnekte, işaretçi yöntem adlarından birine karşılık gelen bir sözcüğün üzerindeyken QuickInfo görüntülenir. QuickInfo denetleyicisi, QuickInfo oturumunu tetikleyen bir fare üzerine gelme olay işleyicisi uygular.

QuickInfo denetleyicisi uygulamak için

  1. uygulayan IIntellisenseControllerbir sınıf bildirin ve adını verin TestQuickInfoController.

    internal class TestQuickInfoController : IIntellisenseController
    
  2. Metin görünümü, metin görünümünde temsil edilen metin arabellekleri, QuickInfo oturumu ve QuickInfo denetleyici sağlayıcısı için özel alanlar ekleyin.

    private ITextView m_textView;
    private IList<ITextBuffer> m_subjectBuffers;
    private TestQuickInfoControllerProvider m_provider;
    private IQuickInfoSession m_session;
    
  3. Alanları ayarlayan ve fareyle vurgulama olay işleyicisini ekleyen bir oluşturucu ekleyin.

    internal TestQuickInfoController(ITextView textView, IList<ITextBuffer> subjectBuffers, TestQuickInfoControllerProvider provider)
    {
        m_textView = textView;
        m_subjectBuffers = subjectBuffers;
        m_provider = provider;
    
        m_textView.MouseHover += this.OnTextViewMouseHover;
    }
    
  4. QuickInfo oturumunu tetikleyen fare üzerine gelme olay işleyicisini ekleyin.

    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. Detach Denetleyici metin görünümünden ayrılırken farenin üzerine gelme olay işleyicisini kaldırması için yöntemini uygulayın.

    public void Detach(ITextView textView)
    {
        if (m_textView == textView)
        {
            m_textView.MouseHover -= this.OnTextViewMouseHover;
            m_textView = null;
        }
    }
    
  6. ConnectSubjectBuffer bu örnek için yöntemini ve DisconnectSubjectBuffer yöntemini boş yöntemler olarak uygulayın.

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

QuickInfo denetleyici sağlayıcısını uygulama

QuickInfo denetleyicisinin sağlayıcısı öncelikle kendisini MEF bileşeni parçası olarak dışarı aktarmaya ve QuickInfo denetleyicisinin örneğini oluşturmaya hizmet eder. Bu bir MEF bileşeni parçası olduğundan, diğer MEF bileşen parçalarını içeri aktarabilir.

QuickInfo denetleyici sağlayıcısını uygulamak için

  1. uygulayan IIntellisenseControllerProvideradlı TestQuickInfoControllerProvider bir sınıf bildirin ve bunu "ToolTip QuickInfo Controller" ve ContentTypeAttribute "text" ile NameAttribute dışarı aktarın:

    [Export(typeof(IIntellisenseControllerProvider))]
    [Name("ToolTip QuickInfo Controller")]
    [ContentType("text")]
    internal class TestQuickInfoControllerProvider : IIntellisenseControllerProvider
    
  2. özelliğini bir özellik olarak içeri aktarın IQuickInfoBroker .

    [Import]
    internal IQuickInfoBroker QuickInfoBroker { get; set; }
    
  3. QuickInfo denetleyicisini TryCreateIntellisenseController başlatarak yöntemini uygulayın.

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

Kodu derleme ve test etme

Bu kodu test etmek için QuickInfoTest çözümünü derleyin ve deneysel örnekte çalıştırın.

QuickInfoTest çözümünü derlemek ve test etmek için

  1. Çözümü oluşturun.

  2. Bu projeyi hata ayıklayıcıda çalıştırdığınızda, Visual Studio'nun ikinci bir örneği başlatılır.

  3. Bir metin dosyası oluşturun ve "ekle" ve "çıkar" sözcüklerini içeren bir metin yazın.

  4. İşaretçiyi "ekle" örneğinden birinin üzerine getirin. yöntemin imzası ve açıklaması add görüntülenmelidir.