İzlenecek yol: Düzenleyici uzantısıyla kısayol tuşu kullanma

Düzenleyici uzantınızdaki kısayol tuşlarını yanıtlayabilirsiniz. Aşağıdaki kılavuzda, kısayol tuşu kullanarak metin görünümüne görünüm süslemesinin nasıl ekleneceği gösterilmektedir. Bu izlenecek yol, görünüm penceresi kenarlık düzenleyicisi şablonunu temel alır ve + karakterini kullanarak donatma eklemenize olanak tanı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ü KeyBindingTestolarak adlandırın.

  2. Projeye bir Düzenleyici Metin Donatısı öğesi şablonu ekleyin ve adını verin KeyBindingTest. Daha fazla bilgi için bkz . Düzenleyici Öğesi Şablonu ile Uzantı Oluşturma.

  3. Aşağıdaki başvuruları ekleyin ve CopyLocal değerini olarak falseayarlayın:

    Microsoft.VisualStudio.Editor

    Microsoft.visualstudio.ole

    Microsoft.VisualStudio.Shell.14.0

    Microsoft.VisualStudio.TextManager.Interop

    KeyBindingTest sınıf dosyasında sınıf adını PurpleCornerBox olarak değiştirin. Diğer uygun değişiklikleri yapmak için sol kenar boşluğunda görünen ampulü kullanın. Oluşturucunun içinde, KeyBindingTest olan donatma katmanının adını PurpleCornerBox olarak değiştirin:

this.layer = view.GetAdornmentLayer("PurpleCornerBox");

KeyBindingTestTextViewCreationListener.cs sınıf dosyasında AdornmentLayer'ın adını KeyBindingTest yerine PurpleCornerBox olarak değiştirin:

[Export(typeof(AdornmentLayerDefinition))]
[Name("PurpleCornerBox")]
[Order(After = PredefinedAdornmentLayers.Selection, Before = PredefinedAdornmentLayers.Text)]
public AdornmentLayerDefinition editorAdornmentLayer;

TYPECHAR komutunu işleme

Visual Studio 2017 sürüm 15.6'nın öncesinde, düzenleyici uzantısındaki komutları işlemenin tek yolu, tabanlı bir IOleCommandTarget komut filtresi uygulamaktı. Visual Studio 2017 sürüm 15.6, düzenleyici komut işleyicilerini temel alan modern bir basitleştirilmiş yaklaşım kullanıma sunulmuştur. Sonraki iki bölümde, hem eski hem de modern yaklaşımı kullanarak bir komutun nasıl işleneceğini gösterilmektedir.

Komut filtresini tanımlama (Visual Studio 2017 sürüm 15.6'nın öncesinde)

Komut filtresi, donatma örneği oluşturarak komutu işleyen bir uygulamasıdır IOleCommandTarget.

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

  2. Aşağıdaki using yönergelerini ekleyin.

    using System;
    using System.Runtime.InteropServices;
    using Microsoft.VisualStudio.OLE.Interop;
    using Microsoft.VisualStudio;
    using Microsoft.VisualStudio.Text.Editor;
    
    
  3. KeyBindingCommandFilter adlı sınıf öğesinden IOleCommandTargetdevralmalıdır.

    internal class KeyBindingCommandFilter : IOleCommandTarget
    
  4. Metin görünümü için özel alanlar, komut zincirindeki bir sonraki komut ve komut filtresinin zaten eklenip eklenmediğini gösteren bir bayrak ekleyin.

    private IWpfTextView m_textView;
    internal IOleCommandTarget m_nextTarget;
    internal bool m_added;
    internal bool m_adorned;
    
  5. Metin görünümünü ayarlayan bir oluşturucu ekleyin.

    public KeyBindingCommandFilter(IWpfTextView textView)
    {
        m_textView = textView;
        m_adorned = false;
    }
    
  6. QueryStatus() yöntemini aşağıdaki gibi uygulayın.

    int IOleCommandTarget.QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText)
    {
        return m_nextTarget.QueryStatus(ref pguidCmdGroup, cCmds, prgCmds, pCmdText);
    }
    
  7. Exec() Artı işareti (+) karakteri yazıldıysa görünüme mor bir kutu eklemek için yöntemini uygulayın.

    int IOleCommandTarget.Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
    {
        if (m_adorned == false)
        {
            char typedChar = char.MinValue;
    
            if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR)
            {
                typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn);
                if (typedChar.Equals('+'))
                {
                    new PurpleCornerBox(m_textView);
                    m_adorned = true;
                }
            }
        }
        return m_nextTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
    }
    
    

Komut filtresini ekleme (Visual Studio 2017 sürüm 15.6'nın öncesinde)

Donatma sağlayıcısının metin görünümüne bir komut filtresi eklemesi gerekir. Bu örnekte, sağlayıcı metin görünümü oluşturma olaylarını IVsTextViewCreationListener dinlemek için uygular. Bu donatma sağlayıcısı ayrıca, donatma katmanının Z sırasını tanımlayan donatma katmanını da dışarı aktarır.

  1. KeyBindingTestTextViewCreationListener dosyasına aşağıdaki using yönergelerini ekleyin:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.Composition;
    using Microsoft.VisualStudio;
    using Microsoft.VisualStudio.OLE.Interop;
    using Microsoft.VisualStudio.Utilities;
    using Microsoft.VisualStudio.Editor;
    using Microsoft.VisualStudio.Text.Editor;
    using Microsoft.VisualStudio.TextManager.Interop;
    
    
  2. Metin görünümü bağdaştırıcısını almak için öğesini içeri aktarmanız IVsEditorAdaptersFactoryServicegerekir.

    [Import(typeof(IVsEditorAdaptersFactoryService))]
    internal IVsEditorAdaptersFactoryService editorFactory = null;
    
    
  3. TextViewCreated yöntemini, öğesini ekleyebilecek şekilde KeyBindingCommandFilterdeğiştirin.

    public void TextViewCreated(IWpfTextView textView)
    {
        AddCommandFilter(textView, new KeyBindingCommandFilter(textView));
    }
    
  4. İşleyici AddCommandFilter metin görünümü bağdaştırıcısını alır ve komut filtresini ekler.

    void AddCommandFilter(IWpfTextView textView, KeyBindingCommandFilter commandFilter)
    {
        if (commandFilter.m_added == false)
        {
            //get the view adapter from the editor factory
            IOleCommandTarget next;
            IVsTextView view = editorFactory.GetViewAdapter(textView);
    
            int hr = view.AddCommandFilter(commandFilter, out next);
    
            if (hr == VSConstants.S_OK)
            {
                commandFilter.m_added = true;
                 //you'll need the next target for Exec and QueryStatus
                if (next != null)
                commandFilter.m_nextTarget = next;
            }
        }
    }
    

Komut işleyicisi uygulama (Visual Studio 2017 sürüm 15.6'dan başlayarak)

İlk olarak, en son düzenleyici API'sine başvurmak için projenin Nuget başvurularını güncelleştirin:

  1. Projeye sağ tıklayın ve Nuget Paketlerini Yönet'i seçin.

  2. Nuget Paket Yöneticisi'da Güncelleştirmeler sekmesini, Tüm paketleri seç onay kutusunu ve ardından Güncelleştir'i seçin.

Komut işleyicisi, donatma örneği oluşturarak komutu işleyen bir uygulamasıdır ICommandHandler<T>.

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

  2. Aşağıdaki using yönergelerini ekleyin.

    using Microsoft.VisualStudio.Commanding;
    using Microsoft.VisualStudio.Text.Editor;
    using Microsoft.VisualStudio.Text.Editor.Commanding.Commands;
    using Microsoft.VisualStudio.Utilities;
    using System.ComponentModel.Composition;
    
  3. KeyBindingCommandHandler adlı sınıf öğesinden ICommandHandler<TypeCharCommandArgs>devralmalı ve olarak ICommandHandlerdışarı aktarmalıdır:

    [Export(typeof(ICommandHandler))]
    [ContentType("text")]
    [Name("KeyBindingTest")]
    internal class KeyBindingCommandHandler : ICommandHandler<TypeCharCommandArgs>
    
  4. Komut işleyicisinin görünen adını ekleyin:

    public string DisplayName => "KeyBindingTest";
    
  5. GetCommandState() yöntemini aşağıdaki gibi uygulayın. Bu komut işleyicisi çekirdek düzenleyici TYPECHAR komutunu işlediğinden, komutun etkinleştirilmesini çekirdek düzenleyiciye devredebilir.

    public CommandState GetCommandState(TypeCharCommandArgs args)
    {
        return CommandState.Unspecified;
    }
    
  6. ExecuteCommand() Artı işareti (+) karakteri yazıldıysa görünüme mor bir kutu eklemek için yöntemini uygulayın.

    public bool ExecuteCommand(TypeCharCommandArgs args, CommandExecutionContext executionContext)
    {
        if (args.TypedChar == '+')
        {
            bool alreadyAdorned = args.TextView.Properties.TryGetProperty(
                "KeyBindingTextAdorned", out bool adorned) && adorned;
            if (!alreadyAdorned)
            {
                new PurpleCornerBox((IWpfTextView)args.TextView);
                args.TextView.Properties.AddProperty("KeyBindingTextAdorned", true);
            }
        }
    
        return false;
    }
    
    1. KeyBindingTestTextViewCreationListener.cs dosyasındaki donatma katmanı tanımını KeyBindingCommandHandler.cs dosyasına kopyalayın ve ardından KeyBindingTestTextViewCreationListener.cs dosyasını silin:
    /// <summary>
    /// Defines the adornment layer for the adornment. This layer is ordered
    /// after the selection layer in the Z-order.
    /// </summary>
    [Export(typeof(AdornmentLayerDefinition))]
    [Name("PurpleCornerBox")]
    [Order(After = PredefinedAdornmentLayers.Selection, Before = PredefinedAdornmentLayers.Text)]
    private AdornmentLayerDefinition editorAdornmentLayer;
    

Süslemenin her satırda görünmesini sağlama

Özgün süsleme, bir metin dosyasındaki her 'a' karakterinde görüntülenir. Artık karaktere yanıt olarak betiği eklemek için kodu değiştirdiğimize göre + , bu özellik yalnızca karakterin yazıldığı satıra + ekler. Donatma kodunu, her 'a' üzerinde bir kez daha görünecek şekilde değiştirebiliriz.

KeyBindingTest.cs dosyasında, 'a' karakterini süslemek için görünümdeki tüm satırlarda yinelemek için yöntemini değiştirinCreateVisuals().

private void CreateVisuals(ITextViewLine line)
{
    IWpfTextViewLineCollection textViewLines = this.view.TextViewLines;

    foreach (ITextViewLine textViewLine in textViewLines)
    {
        if (textViewLine.ToString().Contains("a"))
        {
            // Loop through each character, and place a box around any 'a'
            for (int charIndex = textViewLine.Start; charIndex < textViewLine.End; charIndex++)
            {
                if (this.view.TextSnapshot[charIndex] == 'a')
                {
                    SnapshotSpan span = new SnapshotSpan(this.view.TextSnapshot, Span.FromBounds(charIndex, charIndex + 1));
                    Geometry geometry = textViewLines.GetMarkerGeometry(span);
                    if (geometry != null)
                    {
                        var drawing = new GeometryDrawing(this.brush, this.pen, geometry);
                        drawing.Freeze();

                        var drawingImage = new DrawingImage(drawing);
                        drawingImage.Freeze();

                        var image = new Image
                        {
                            Source = drawingImage,
                        };

                        // Align the image with the top of the bounds of the text geometry
                        Canvas.SetLeft(image, geometry.Bounds.Left);
                        Canvas.SetTop(image, geometry.Bounds.Top);

                        this.layer.AddAdornment(AdornmentPositioningBehavior.TextRelative, span, null, image, null);
                    }
                }
            }
        }
    }
}

Kodu derleme ve test etme

  1. KeyBindingTest çözümünü derleyin ve deneysel örnekte çalıştırın.

  2. Metin dosyası oluşturun veya açın. 'a' karakterini içeren bazı sözcükler yazın ve sonra metin görünümünde herhangi bir yere yazın + .

    Dosyadaki her 'a' karakterinde mor bir kare görünmelidir.