Freigeben über


Exemplarische Vorgehensweise: Verwenden einer Tastenkombination mit einer Editorerweiterung

Sie können auf Tastenkombinationen in der Editorerweiterung reagieren. In der folgenden exemplarischen Vorgehensweise wird gezeigt, wie Sie einer Textansicht mithilfe einer Tastenkombination eine Ansichtsverzierung hinzufügen. Diese exemplarische Vorgehensweise basiert auf der Viewport-Zier-Editor-Vorlage und ermöglicht es Ihnen, das Zierelement mithilfe des Zeichens +hinzuzufügen.

Erstellen eines Verwalteten Erweiterbarkeitsframeworks (MEF)-Projekts

  1. Erstellen Sie ein C#VSIX-Projekt. (Im Dialogfeld "Neues Projekt ", wählen Sie Visual C# / Erweiterbarkeit und dann VSIX-Projekt aus.) Benennen Sie die Lösung KeyBindingTest.

  2. Fügen Sie dem Projekt eine Elementvorlage für Editortext-Schmücken hinzu, und nennen Sie sie KeyBindingTest. Weitere Informationen finden Sie unter Erstellen einer Erweiterung mit einer Editorelementvorlage.

  3. Fügen Sie die folgenden Verweise hinzu, und legen Sie CopyLocal auf false:

    Microsoft.VisualStudio.Editor

    Microsoft.VisualStudio.OLE.Interop

    Microsoft.VisualStudio.Shell.14.0

    Microsoft.VisualStudio.TextManager.Interop

    Ändern Sie in der KeyBindingTest-Klassendatei den Klassennamen in PurpleCornerBox. Verwenden Sie die Glühbirne, die am linken Rand angezeigt wird, um die anderen geeigneten Änderungen vorzunehmen. Ändern Sie im Konstruktor den Namen der Schmückenebene von KeyBindingTest in PurpleCornerBox:

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

Ändern Sie in der Klassendatei KeyBindingTestViewCreationListener.cs den Namen des AdornmentLayer von KeyBindingTest in PurpleCornerBox:

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

Handle TYPECHAR command

Vor Visual Studio 2017, Version 15.6, war die einzige Möglichkeit, Befehle in einer Editorerweiterung zu behandeln, einen IOleCommandTarget basierten Befehlsfilter implementiert. Visual Studio 2017, Version 15.6, hat einen modernen vereinfachten Ansatz eingeführt, der auf Editorbefehlshandlern basiert. In den nächsten beiden Abschnitten wird veranschaulicht, wie sie einen Befehl sowohl mit dem älteren als auch dem modernen Ansatz behandeln.

Definieren des Befehlsfilters (vor Visual Studio 2017, Version 15.6)

Der Befehlsfilter ist eine Implementierung von IOleCommandTarget, die den Befehl durch Instanziieren der Dekoration behandelt.

  1. Fügen Sie eine Klassendatei hinzu, und nennen Sie sie KeyBindingCommandFilter.

  2. Fügen Sie die folgenden using-Direktiven hinzu.

    using System;
    using System.Runtime.InteropServices;
    using Microsoft.VisualStudio.OLE.Interop;
    using Microsoft.VisualStudio;
    using Microsoft.VisualStudio.Text.Editor;
    
    
  3. Die Klasse mit dem Namen KeyBindingCommandFilter sollte von IOleCommandTarget.

    internal class KeyBindingCommandFilter : IOleCommandTarget
    
  4. Fügen Sie private Felder für die Textansicht, den nächsten Befehl in der Befehlskette und ein Flag hinzu, um darzustellen, ob der Befehlsfilter bereits hinzugefügt wurde.

    private IWpfTextView m_textView;
    internal IOleCommandTarget m_nextTarget;
    internal bool m_added;
    internal bool m_adorned;
    
  5. Fügen Sie einen Konstruktor hinzu, der die Textansicht festlegt.

    public KeyBindingCommandFilter(IWpfTextView textView)
    {
        m_textView = textView;
        m_adorned = false;
    }
    
  6. Implementieren Sie die QueryStatus() Methode wie folgt.

    int IOleCommandTarget.QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText)
    {
        return m_nextTarget.QueryStatus(ref pguidCmdGroup, cCmds, prgCmds, pCmdText);
    }
    
  7. Implementieren Sie die Exec() Methode so, dass der Ansicht ein violettes Feld hinzugefügt wird, wenn ein Pluszeichen (+) eingegeben wird.

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

Hinzufügen des Befehlsfilters (vor Visual Studio 2017, Version 15.6)

Der Zieranbieter muss der Textansicht einen Befehlsfilter hinzufügen. In diesem Beispiel implementiert der Anbieter das Überwachen von Textansichts-Erstellungsereignissen IVsTextViewCreationListener . Dieser Zieranbieter exportiert auch die Zierschicht, die die Z-Ordnung der Dekoration definiert.

  1. Fügen Sie in der Datei "KeyBindingTestTextViewCreationListener" die folgenden Direktiven hinzu:

    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. Um den Textansichtsadapter abzurufen, müssen Sie den IVsEditorAdaptersFactoryService.

    [Import(typeof(IVsEditorAdaptersFactoryService))]
    internal IVsEditorAdaptersFactoryService editorFactory = null;
    
    
  3. Ändern Sie die TextViewCreated Methode so, dass sie die KeyBindingCommandFilter.

    public void TextViewCreated(IWpfTextView textView)
    {
        AddCommandFilter(textView, new KeyBindingCommandFilter(textView));
    }
    
  4. Der AddCommandFilter Handler ruft den Textansichtsadapter ab und fügt den Befehlsfilter hinzu.

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

Implementieren eines Befehlshandlers (ab Visual Studio 2017, Version 15.6)

Aktualisieren Sie zunächst die Nuget-Verweise des Projekts, um auf die neueste Editor-API zu verweisen:

  1. Klicken Sie mit der rechten Maustaste auf das Projekt, und wählen Sie "Nuget-Pakete verwalten" aus.

  2. Aktivieren Sie in Nuget Paket-Manager die Registerkarte "Updates", aktivieren Sie das Kontrollkästchen "Alle Pakete auswählen", und wählen Sie dann "Aktualisieren" aus.

Der Befehlshandler ist eine Implementierung von ICommandHandler<T>, die den Befehl durch Instanziieren der Dekoration behandelt.

  1. Fügen Sie eine Klassendatei hinzu, und nennen Sie sie KeyBindingCommandHandler.

  2. Fügen Sie die folgenden using-Direktiven hinzu.

    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. Die Klasse mit dem Namen KeyBindingCommandHandler sollte von ICommandHandler<TypeCharCommandArgs>dem erben und exportieren als ICommandHandler:

    [Export(typeof(ICommandHandler))]
    [ContentType("text")]
    [Name("KeyBindingTest")]
    internal class KeyBindingCommandHandler : ICommandHandler<TypeCharCommandArgs>
    
  4. Fügen Sie einen Anzeigenamen des Befehlshandlers hinzu:

    public string DisplayName => "KeyBindingTest";
    
  5. Implementieren Sie die GetCommandState() Methode wie folgt. Da dieser Befehlshandler den Kern-Editor TYPECHAR-Befehl behandelt, kann er die Aktivierung des Befehls an den Kern-Editor delegieren.

    public CommandState GetCommandState(TypeCharCommandArgs args)
    {
        return CommandState.Unspecified;
    }
    
  6. Implementieren Sie die ExecuteCommand() Methode so, dass der Ansicht ein violettes Feld hinzugefügt wird, wenn ein Pluszeichen (+) eingegeben wird.

    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. Kopieren Sie die Definition der Schmückenebene aus der Datei "KeyBindingTestTextViewCreationListener.cs" in die Datei "KeyBindingCommandHandler.cs", und löschen Sie dann die Datei "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;
    

Sorgen Sie dafür, dass die Dekoration auf jeder Linie angezeigt wird.

Das ursprüngliche Zierelement erschien auf jedem Zeichen "a" in einer Textdatei. Nachdem wir nun den Code geändert haben, um das Zierzeichen als Reaktion auf das + Zeichen hinzuzufügen, fügt es die Verzierung nur in der Zeile hinzu, in der das + Zeichen eingegeben wird. Wir können den Ziercode so ändern, dass die Verzierung einmal mehr auf jedem "a" erscheint.

Ändern Sie in der Datei "KeyBindingTest.cs " die CreateVisuals() Methode so, dass alle Zeilen in der Ansicht durchlaufen werden, um das Zeichen "a" zu schmücken.

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

Erstellen und Testen des Codes

  1. Erstellen Sie die KeyBindingTest-Lösung, und führen Sie sie in der experimentellen Instanz aus.

  2. Erstellen oder Öffnen einer Textdatei. Geben Sie einige Wörter ein, die das Zeichen "a" enthalten, und geben Sie + dann eine beliebige Stelle in der Textansicht ein.

    Ein violettes Quadrat sollte auf jedem "a"-Zeichen in der Datei angezeigt werden.