İzlenecek yol: Ampul önerilerini görüntüleme

Ampuller, Visual Studio düzenleyicisinde yerleşik kod çözümleyicileri veya kod yeniden düzenleme tarafından tanımlanan sorunlara yönelik düzeltmeler gibi bir dizi eylemi görüntüleyecek şekilde genişletilen simgelerdir.

Visual C# ve Visual Basic düzenleyicilerinde, ampulleri otomatik olarak görüntüleyen eylemlerle kendi kod çözümleyicilerinizi yazmak ve paketlemek için .NET Derleyici Platformu'nu ("Roslyn") de kullanabilirsiniz. Daha fazla bilgi için bkz.

  • Nasıl Yapılır: C# tanılama ve kod düzeltmesi yazma

  • Nasıl Yapılır: Visual Basic tanılama ve kod düzeltmesi yazma

    C++ gibi diğer diller de bu işlevin saplama uygulamasını oluşturma önerisi gibi bazı hızlı işlemler için ampuller sağlar.

    Ampul şöyle görünür. Visual Basic veya Visual C# projesinde, geçersiz olduğunda değişken adının altında kırmızı dalgalı bir dalgalı çizgi görünür. Fareyle geçersiz tanımlayıcının üzerine gelirseniz imlecin yanında bir ampul görünür.

    light bulb

    Ampulün yanındaki aşağı oka tıklarsanız, seçilen eylemin önizlemesiyle birlikte bir dizi önerilen eylem görüntülenir. Bu durumda, eylemi yürütürseniz kodunuzda yapılan değişiklikleri gösterir.

    light bulb preview

    Ampulleri kendi önerilen eylemlerinizi sağlamak için kullanabilirsiniz. Örneğin, küme ayraçlarını açma küme ayraçlarını yeni bir satıra taşımaya veya önceki satırın sonuna taşımaya yönelik eylemler sağlayabilirsiniz. Aşağıdaki kılavuzda, geçerli sözcükte görünen ve iki önerilen eylem içeren bir ampulün nasıl oluşturulacağı gösterilmektedir: Büyük harfe dönüştür ve Küçük harfe dönüştür.

Yönetilen Genişletilebilirlik Çerçevesi (MEF) projesi oluşturma

  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ü LightBulbTestolarak 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.

  4. Projeye aşağıdaki başvuruyu ekleyin ve Yerel Kopyala'yı olarak Falseayarlayın:

    Microsoft.VisualStudio.Language.Intellisense

  5. Yeni bir sınıf dosyası ekleyin ve dosyayı LightBulbTest olarak adlandırnın.

  6. Aşağıdaki kullanım yönergelerini ekleyin:

    using System;
    using System.Linq;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using Microsoft.VisualStudio.Language.Intellisense;
    using Microsoft.VisualStudio.Text;
    using Microsoft.VisualStudio.Text.Editor;
    using Microsoft.VisualStudio.Text.Operations;
    using Microsoft.VisualStudio.Utilities;
    using System.ComponentModel.Composition;
    using System.Threading;
    
    

Ampul kaynak sağlayıcısını uygulama

  1. LightBulbTest.cs sınıf dosyasında LightBulbTest sınıfını silin. uygulayan ISuggestedActionsSourceProviderTestSuggestedActionsSourceProvider adlı bir sınıf ekleyin. Test Önerilen Eylemlerinin Adı ve ContentTypeAttribute "metin" ile dışarı aktarın.

    [Export(typeof(ISuggestedActionsSourceProvider))]
    [Name("Test Suggested Actions")]
    [ContentType("text")]
    internal class TestSuggestedActionsSourceProvider : ISuggestedActionsSourceProvider
    
  2. Kaynak sağlayıcı sınıfının içinde öğesini içeri aktarın ITextStructureNavigatorSelectorService ve bir özellik olarak ekleyin.

    [Import(typeof(ITextStructureNavigatorSelectorService))]
    internal ITextStructureNavigatorSelectorService NavigatorService { get; set; }
    
  3. CreateSuggestedActionsSource Bir ISuggestedActionsSource nesne döndürmek için yöntemini uygulayın. Kaynak, sonraki bölümde ele alınmıştı.

    public ISuggestedActionsSource CreateSuggestedActionsSource(ITextView textView, ITextBuffer textBuffer)
    {
        if (textBuffer == null || textView == null)
        {
            return null;
        }
        return new TestSuggestedActionsSource(this, textView, textBuffer);
    }
    

ISuggestedActionSource'ı uygulama

Önerilen eylem kaynağı, önerilen eylemler kümesini toplamak ve bunları doğru bağlamda eklemekle sorumludur. Bu durumda bağlam geçerli sözcük ve önerilen eylemler aşağıdaki bölümde açıklanan UpperCaseSuggestedAction ve LowerCaseSuggestedAction'dır.

  1. uygulayan ISuggestedActionsSourcebir TestSuggestedActionsSource sınıfı ekleyin.

    internal class TestSuggestedActionsSource : ISuggestedActionsSource
    
  2. Önerilen eylem kaynağı sağlayıcısı, metin arabelleği ve metin görünümü için özel, salt okunur alanlar ekleyin.

    private readonly TestSuggestedActionsSourceProvider m_factory;
    private readonly ITextBuffer m_textBuffer;
    private readonly ITextView m_textView;
    
  3. Özel alanları ayarlayan bir oluşturucu ekleyin.

    public TestSuggestedActionsSource(TestSuggestedActionsSourceProvider testSuggestedActionsSourceProvider, ITextView textView, ITextBuffer textBuffer)
    {
        m_factory = testSuggestedActionsSourceProvider;
        m_textBuffer = textBuffer;
        m_textView = textView;
    }
    
  4. İmlecin altında bulunan sözcüğü döndüren özel bir yöntem ekleyin. Aşağıdaki yöntem imlecin geçerli konumuna bakar ve metin yapısı gezgininden sözcüğün kapsamını sorar. İmleç bir sözcüğün üzerindeyse out TextExtent parametresinde döndürülür; aksi takdirde out parametresi olur null ve yöntemi döndürür false.

    private bool TryGetWordUnderCaret(out TextExtent wordExtent)
    {
        ITextCaret caret = m_textView.Caret;
        SnapshotPoint point;
    
        if (caret.Position.BufferPosition > 0)
        {
            point = caret.Position.BufferPosition - 1;
        }
        else
        {
            wordExtent = default(TextExtent);
            return false;
        }
    
        ITextStructureNavigator navigator = m_factory.NavigatorService.GetTextStructureNavigator(m_textBuffer);
    
        wordExtent = navigator.GetExtentOfWord(point);
        return true;
    }
    
  5. HasSuggestedActionsAsync yöntemini uygulayın. Düzenleyici ampulün görüntülenip görüntülenmeyeceğini öğrenmek için bu yöntemi çağırır. Bu çağrı genellikle yapılır, örneğin, imleç bir satırdan diğerine geçtiğinde veya fare bir hata dalgalı çizginin üzerine geldiğinde. Bu yöntem çalışırken diğer ui işlemlerinin devam edebilmesi için zaman uyumsuzdur. Çoğu durumda, bu yöntemin geçerli satırın ayrıştırması ve analizini gerçekleştirmesi gerekir, bu nedenle işlem biraz zaman alabilir.

    Bu uygulamada, zaman uyumsuz olarak TextExtent alır ve kapsamın önemli olup olmadığını belirler, örneğin, boşluk dışında bir metni olup olmadığını.

    public Task<bool> HasSuggestedActionsAsync(ISuggestedActionCategorySet requestedActionCategories, SnapshotSpan range, CancellationToken cancellationToken)
    {
        return Task.Factory.StartNew(() =>
        {
            TextExtent extent;
            if (TryGetWordUnderCaret(out extent))
            {
                // don't display the action if the extent has whitespace
                return extent.IsSignificant;
              }
            return false;
        });
    }
    
  6. GetSuggestedActions Farklı ISuggestedAction nesneleri içeren bir nesne dizisi SuggestedActionSet döndüren yöntemini uygulayın. Ampul genişletildiğinde bu yöntem çağrılır.

    Uyarı

    ve uygulamalarının HasSuggestedActionsAsync() tutarlı olduğundan emin olmalısınız; yani döndürürse HasSuggestedActionsAsync()true, GetSuggestedActions() görüntülenecek bazı eylemleri GetSuggestedActions() olmalıdır. Çoğu durumda, HasSuggestedActionsAsync() hemen önce GetSuggestedActions()çağrılır, ancak her zaman böyle değildir. Örneğin, kullanıcı ampul eylemlerini yalnızca GetSuggestedActions() (CTRL+ .) tuşlarına basarak çağırırsa çağrılır.

    public IEnumerable<SuggestedActionSet> GetSuggestedActions(ISuggestedActionCategorySet requestedActionCategories, SnapshotSpan range, CancellationToken cancellationToken)
    {
        TextExtent extent;
        if (TryGetWordUnderCaret(out extent) && extent.IsSignificant)
        {
            ITrackingSpan trackingSpan = range.Snapshot.CreateTrackingSpan(extent.Span, SpanTrackingMode.EdgeInclusive);
            var upperAction = new UpperCaseSuggestedAction(trackingSpan);
            var lowerAction = new LowerCaseSuggestedAction(trackingSpan);
            return new SuggestedActionSet[] { new SuggestedActionSet(new ISuggestedAction[] { upperAction, lowerAction }) };
        }
        return Enumerable.Empty<SuggestedActionSet>();
    }
    
  7. Bir SuggestedActionsChanged olay tanımlayın.

    public event EventHandler<EventArgs> SuggestedActionsChanged;
    
  8. Uygulamayı tamamlamak için ve TryGetTelemetryId() yöntemlerine Dispose() yönelik uygulamalar ekleyin. Telemetri yapmak istemediğiniz için guid değerini döndürerek false olarak ayarlamanız gerekir Empty.

    public void Dispose()
    {
    }
    
    public bool TryGetTelemetryId(out Guid telemetryId)
    {
        // This is a sample provider and doesn't participate in LightBulb telemetry
        telemetryId = Guid.Empty;
        return false;
    }
    

Ampul eylemlerini uygulama

  1. Projede, Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime.dll dosyasına bir başvuru ekleyin ve Yerel Kopyala'yı olarak Falseayarlayın.

  2. İlk ve ikinci adlı UpperCaseSuggestedActionLowerCaseSuggestedActioniki sınıf oluşturun. Her iki sınıf da uygular ISuggestedAction.

    internal class UpperCaseSuggestedAction : ISuggestedAction
    internal class LowerCaseSuggestedAction : ISuggestedAction
    

    Bir çağrı ve diğer ToLowerçağrıları ToUpper dışında her iki sınıf da birbirine benzer. Aşağıdaki adımlar yalnızca büyük harf eylem sınıfını kapsar, ancak her iki sınıfı da uygulamanız gerekir. Büyük harf eylemini küçük harf eylemini uygulamak için bir desen olarak uygulama adımlarını kullanın.

  3. Bu sınıflar için aşağıdaki using yönergelerini ekleyin:

    using Microsoft.VisualStudio.Imaging.Interop;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Media;
    
    
  4. Bir dizi özel alan bildirin.

    private ITrackingSpan m_span;
    private string m_upper;
    private string m_display;
    private ITextSnapshot m_snapshot;
    
  5. Alanları ayarlayan bir oluşturucu ekleyin.

    public UpperCaseSuggestedAction(ITrackingSpan span)
    {
        m_span = span;
        m_snapshot = span.TextBuffer.CurrentSnapshot;
        m_upper = span.GetText(m_snapshot).ToUpper();
        m_display = string.Format("Convert '{0}' to upper case", span.GetText(m_snapshot));
    }
    
  6. Eylemin önizlemesini GetPreviewAsync görüntülemesi için yöntemini uygulayın.

    public Task<object> GetPreviewAsync(CancellationToken cancellationToken)
    {
        var textBlock = new TextBlock();
        textBlock.Padding = new Thickness(5);
        textBlock.Inlines.Add(new Run() { Text = m_upper });
        return Task.FromResult<object>(textBlock);
    }
    
  7. GetActionSetsAsync boş bir SuggestedActionSet numaralandırma döndürmek için yöntemini uygulayın.

    public Task<IEnumerable<SuggestedActionSet>> GetActionSetsAsync(CancellationToken cancellationToken)
    {
        return Task.FromResult<IEnumerable<SuggestedActionSet>>(null);
    }
    
  8. Özellikleri aşağıdaki gibi uygulayın.

    public bool HasActionSets
    {
        get { return false; }
    }
    public string DisplayText
    {
        get { return m_display; }
    }
    public ImageMoniker IconMoniker
    {
       get { return default(ImageMoniker); }
    }
    public string IconAutomationText
    {
        get
        {
            return null;
        }
    }
    public string InputGestureText
    {
        get
        {
            return null;
        }
    }
    public bool HasPreview
    {
        get { return true; }
    }
    
  9. span içindeki Invoke metni büyük harf eşdeğeriyle değiştirerek yöntemini uygulayın.

    public void Invoke(CancellationToken cancellationToken)
    {
        m_span.TextBuffer.Replace(m_span.GetSpan(m_snapshot), m_upper);
    }
    

    Uyarı

    Ampul eylemi Invoke yönteminin kullanıcı arabirimini göstermesi beklenmiyor. Eyleminiz yeni bir kullanıcı arabirimi (örneğin bir önizleme veya seçim iletişim kutusu) getirirse, kullanıcı arabirimini doğrudan Invoke yönteminin içinden görüntülemeyin, bunun yerine Invoke'tandöndükten sonra kullanıcı arabiriminizi görüntülemek için zamanlayın.

  10. Uygulamayı tamamlamak için ve TryGetTelemetryId() yöntemlerini ekleyinDispose().

    public void Dispose()
    {
    }
    
    public bool TryGetTelemetryId(out Guid telemetryId)
    {
        // This is a sample action and doesn't participate in LightBulb telemetry
        telemetryId = Guid.Empty;
        return false;
    }
    
  11. Görüntüleme metnini "'' küçük harfe dönüştür{0}" olarak ve çağrısı ToUpperToLowerolarak değiştirmek için LowerCaseSuggestedAction de aynı şeyi yapmayı unutmayın.

Kodu derleme ve test etme

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

  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 metin yazın. Metnin solunda bir ampul görmeniz gerekir.

    test the light bulb

  4. Ampulün üzerine gelin. Aşağı ok görmeniz gerekir.

  5. Ampule tıkladığınızda, seçilen eylemin önizlemesiyle birlikte iki önerilen eylem görüntülenmelidir.

    test light bulb, expanded

  6. İlk eyleme tıklarsanız, geçerli sözcükteki tüm metin büyük harfe dönüştürülmelidir. İkinci eyleme tıklarsanız, tüm metin küçük harfe dönüştürülmelidir.