Bagikan melalui


Panduan: Menggunakan kunci pintasan dengan ekstensi editor

Anda dapat menanggapi kunci pintasan di ekstensi editor Anda. Panduan berikut menunjukkan cara menambahkan hiasan tampilan ke tampilan teks dengan menggunakan kunci pintasan. Panduan ini didasarkan pada templat editor hiasan viewport, dan memungkinkan Anda untuk menambahkan hiasan dengan menggunakan karakter + .

Membuat Proyek Managed Extensibility Framework (MEF)

  1. Buat proyek C# VSIX. (Dalam Dialog Proyek Baru, pilih Visual C# / Ekstensibilitas, lalu Proyek VSIX.) Beri nama solusi KeyBindingTest.

  2. Tambahkan templat item Hiasan Teks Editor ke proyek dan beri nama KeyBindingTest. Untuk informasi selengkapnya, lihat Membuat Ekstensi dengan Templat Item Editor.

  3. Tambahkan referensi berikut dan atur CopyLocal ke false:

    Microsoft.VisualStudio.Editor

    Microsoft.VisualStudio.OLE.Interop

    Microsoft.VisualStudio.Shell.14.0

    Microsoft.VisualStudio.TextManager.Interop

    Dalam file kelas KeyBindingTest, ubah nama kelas menjadi PurpleCornerBox. Gunakan bola lampu yang muncul di margin kiri untuk membuat perubahan lain yang sesuai. Di dalam konstruktor, ubah nama lapisan hiasan dari KeyBindingTest ke PurpleCornerBox:

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

Dalam file kelas KeyBindingTestTextViewCreationListener.cs, ubah nama AdornmentLayer dari KeyBindingTest menjadi PurpleCornerBox:

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

Menangani perintah TYPECHAR

Sebelum Visual Studio 2017 versi 15.6, satu-satunya cara untuk menangani perintah dalam ekstensi editor adalah dengan IOleCommandTarget menerapkan filter perintah berbasis. Visual Studio 2017 versi 15.6 memperkenalkan pendekatan modern yang disederhanakan berdasarkan penanganan perintah editor. Dua bagian berikutnya menunjukkan cara menangani perintah menggunakan pendekatan warisan dan modern.

Tentukan filter perintah (sebelum Visual Studio 2017 versi 15.6)

Filter perintah adalah implementasi dari IOleCommandTarget, yang menangani perintah dengan membuat instans hiasan.

  1. Tambahkan file kelas dan beri nama KeyBindingCommandFilter.

  2. Tambahkan yang berikut ini menggunakan direktif.

    using System;
    using System.Runtime.InteropServices;
    using Microsoft.VisualStudio.OLE.Interop;
    using Microsoft.VisualStudio;
    using Microsoft.VisualStudio.Text.Editor;
    
    
  3. Kelas bernama KeyBindingCommandFilter harus mewarisi dari IOleCommandTarget.

    internal class KeyBindingCommandFilter : IOleCommandTarget
    
  4. Tambahkan bidang privat untuk tampilan teks, perintah berikutnya dalam rantai perintah, dan bendera untuk mewakili apakah filter perintah telah ditambahkan.

    private IWpfTextView m_textView;
    internal IOleCommandTarget m_nextTarget;
    internal bool m_added;
    internal bool m_adorned;
    
  5. Tambahkan konstruktor yang mengatur tampilan teks.

    public KeyBindingCommandFilter(IWpfTextView textView)
    {
        m_textView = textView;
        m_adorned = false;
    }
    
  6. Terapkan QueryStatus() metode sebagai berikut.

    int IOleCommandTarget.QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText)
    {
        return m_nextTarget.QueryStatus(ref pguidCmdGroup, cCmds, prgCmds, pCmdText);
    }
    
  7. Terapkan Exec() metode sehingga menambahkan kotak ungu ke tampilan jika karakter tanda plus (+) ditik.

    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);
    }
    
    

Menambahkan filter perintah (sebelum Visual Studio 2017 versi 15.6)

Penyedia hiasan harus menambahkan filter perintah ke tampilan teks. Dalam contoh ini, penyedia menerapkan IVsTextViewCreationListener untuk mendengarkan peristiwa pembuatan tampilan teks. Penyedia hiasan ini juga mengekspor lapisan hiasan, yang mendefinisikan urutan Z dari hiasan.

  1. Dalam file KeyBindingTestTextViewCreationListener, tambahkan yang berikut ini menggunakan direktif:

    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. Untuk mendapatkan adaptor tampilan teks, Anda harus mengimpor IVsEditorAdaptersFactoryService.

    [Import(typeof(IVsEditorAdaptersFactoryService))]
    internal IVsEditorAdaptersFactoryService editorFactory = null;
    
    
  3. TextViewCreated Ubah metode sehingga menambahkan KeyBindingCommandFilter.

    public void TextViewCreated(IWpfTextView textView)
    {
        AddCommandFilter(textView, new KeyBindingCommandFilter(textView));
    }
    
  4. Handler AddCommandFilter mendapatkan adaptor tampilan teks dan menambahkan filter perintah.

    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;
            }
        }
    }
    

Menerapkan handler perintah (dimulai di Visual Studio 2017 versi 15.6)

Pertama, perbarui referensi Nuget proyek untuk mereferensikan API editor terbaru:

  1. Klik kanan pada proyek dan pilih Kelola Paket Nuget.

  2. Di Pengelola Paket Nuget, pilih tab Pembaruan , pilih kotak centang Pilih semua paket , lalu pilih Perbarui.

Handler perintah adalah implementasi dari ICommandHandler<T>, yang menangani perintah dengan membuat instans hiasan.

  1. Tambahkan file kelas dan beri nama KeyBindingCommandHandler.

  2. Tambahkan yang berikut ini menggunakan direktif.

    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. Kelas bernama KeyBindingCommandHandler harus mewarisi dari ICommandHandler<TypeCharCommandArgs>, dan mengekspornya sebagai ICommandHandler:

    [Export(typeof(ICommandHandler))]
    [ContentType("text")]
    [Name("KeyBindingTest")]
    internal class KeyBindingCommandHandler : ICommandHandler<TypeCharCommandArgs>
    
  4. Tambahkan nama tampilan handler perintah:

    public string DisplayName => "KeyBindingTest";
    
  5. Terapkan GetCommandState() metode sebagai berikut. Karena handler perintah ini menangani perintah TYPECHAR editor inti, ini dapat mendelegasikan mengaktifkan perintah ke editor inti.

    public CommandState GetCommandState(TypeCharCommandArgs args)
    {
        return CommandState.Unspecified;
    }
    
  6. Terapkan ExecuteCommand() metode sehingga menambahkan kotak ungu ke tampilan jika karakter tanda plus (+) ditik.

    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. Salin definisi lapisan hiasan dari file KeyBindingTestTextViewCreationListener.cs ke file KeyBindingCommandHandler.cs lalu hapus file KeyBindingTestTextViewCreationListener.cs:
    /// <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;
    

Buat hiasan muncul di setiap baris

Hiasan asli muncul pada setiap karakter 'a' dalam file teks. Sekarang setelah kita mengubah kode untuk menambahkan hiasan sebagai respons terhadap + karakter, itu menambahkan hiasan hanya pada baris tempat + karakter di ketik. Kita dapat mengubah kode hiasan sehingga hiasan sekali lagi muncul di setiap 'a'.

Dalam file KeyBindingTest.cs, ubah CreateVisuals() metode untuk melakukan iterasi melalui semua baris dalam tampilan untuk menghias karakter 'a'.

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);
                    }
                }
            }
        }
    }
}

Membangun dan menguji kode

  1. Buat solusi KeyBindingTest dan jalankan dalam instans eksperimental.

  2. Membuat atau membuka file teks. Ketik beberapa kata yang berisi karakter 'a', lalu ketik + di mana saja dalam tampilan teks.

    Persegi ungu akan muncul pada setiap karakter 'a' dalam file.