Przewodnik: używanie klawisza skrótu z rozszerzeniem edytora
Możesz odpowiedzieć na klawisze skrótów w rozszerzeniu edytora. W poniższym przewodniku pokazano, jak dodać widok do widoku tekstowego przy użyciu klawisza skrótu. Ten przewodnik jest oparty na szablonie edytora ozdobiania widoku i umożliwia dodanie ozdoby przy użyciu znaku +.
Tworzenie projektu zarządzanej struktury rozszerzalności (MEF)
Utwórz projekt VSIX w języku C#. (W Okno dialogowe Nowy projekt , wybierz pozycję Visual C# / Rozszerzalność, a następnie projekt VSIX. Nadaj rozwiązaniu
KeyBindingTest
nazwę .Dodaj szablon elementu ozdobnego tekstu edytora do projektu i nadaj mu
KeyBindingTest
nazwę . Aby uzyskać więcej informacji, zobacz Tworzenie rozszerzenia za pomocą szablonu elementu edytora.Dodaj następujące odwołania i ustaw wartość CopyLocal na
false
:Microsoft.VisualStudio.Editor
Microsoft.VisualStudio.OLE.Interop
Microsoft.VisualStudio.Shell.14.0
Microsoft.VisualStudio.TextManager.Interop
W pliku klasy KeyBindingTest zmień nazwę klasy na PurpleCornerBox. Użyj żarówki wyświetlanej na lewym marginesie, aby wprowadzić inne odpowiednie zmiany. Wewnątrz konstruktora zmień nazwę warstwy ozdobnej z KeyBindingTest na PurpleCornerBox:
this.layer = view.GetAdornmentLayer("PurpleCornerBox");
W pliku klasy KeyBindingTestTextViewCreationListener.cs zmień nazwę elementu AdornmentLayer z KeyBindingTest na PurpleCornerBox:
[Export(typeof(AdornmentLayerDefinition))]
[Name("PurpleCornerBox")]
[Order(After = PredefinedAdornmentLayers.Selection, Before = PredefinedAdornmentLayers.Text)]
public AdornmentLayerDefinition editorAdornmentLayer;
Obsługa polecenia TYPECHAR
Przed programem Visual Studio 2017 w wersji 15.6 jedynym sposobem obsługi poleceń w rozszerzeniu edytora było zaimplementowanie opartego IOleCommandTarget filtru poleceń. Program Visual Studio 2017 w wersji 15.6 wprowadził nowoczesne uproszczone podejście oparte na programach obsługi poleceń edytora. W kolejnych dwóch sekcjach pokazano, jak obsłużyć polecenie przy użyciu zarówno starszego, jak i nowoczesnego podejścia.
Zdefiniuj filtr poleceń (przed programem Visual Studio 2017 w wersji 15.6)
Filtr poleceń jest implementacją IOleCommandTargetpolecenia , która obsługuje polecenie przez utworzenie wystąpienia elementu adornment.
Dodaj plik klasy i nadaj mu
KeyBindingCommandFilter
nazwę .Dodaj następujące dyrektywy using.
using System; using System.Runtime.InteropServices; using Microsoft.VisualStudio.OLE.Interop; using Microsoft.VisualStudio; using Microsoft.VisualStudio.Text.Editor;
Klasa o nazwie KeyBindingCommandFilter powinna dziedziczyć z klasy IOleCommandTarget.
internal class KeyBindingCommandFilter : IOleCommandTarget
Dodaj pola prywatne dla widoku tekstowego, następne polecenie w łańcuchu poleceń i flagę reprezentującą, czy filtr poleceń został już dodany.
private IWpfTextView m_textView; internal IOleCommandTarget m_nextTarget; internal bool m_added; internal bool m_adorned;
Dodaj konstruktor, który ustawia widok tekstu.
public KeyBindingCommandFilter(IWpfTextView textView) { m_textView = textView; m_adorned = false; }
Zaimplementuj metodę
QueryStatus()
w następujący sposób.int IOleCommandTarget.QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText) { return m_nextTarget.QueryStatus(ref pguidCmdGroup, cCmds, prgCmds, pCmdText); }
Zaimplementuj metodę
Exec()
tak, aby dodaje fioletowe pole do widoku, jeśli znak plus (+) jest wpisany.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); }
Dodaj filtr poleceń (przed programem Visual Studio 2017 w wersji 15.6)
Dostawca dodatków musi dodać filtr poleceń do widoku tekstowego. W tym przykładzie dostawca implementuje IVsTextViewCreationListener nasłuchiwanie zdarzeń tworzenia widoku tekstu. Ten dostawca dodatków eksportuje również warstwę ozdobną, która definiuje kolejność Z elementu ozdobnego.
W pliku KeyBindingTestTextViewCreationListener dodaj następujące dyrektywy using:
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;
Aby uzyskać kartę widoku tekstu, należy zaimportować element IVsEditorAdaptersFactoryService.
[Import(typeof(IVsEditorAdaptersFactoryService))] internal IVsEditorAdaptersFactoryService editorFactory = null;
Zmień metodę tak TextViewCreated , aby dodaje element
KeyBindingCommandFilter
.public void TextViewCreated(IWpfTextView textView) { AddCommandFilter(textView, new KeyBindingCommandFilter(textView)); }
Procedura
AddCommandFilter
obsługi pobiera adapter widoku tekstu i dodaje filtr polecenia.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; } } }
Implementowanie programu obsługi poleceń (począwszy od programu Visual Studio 2017 w wersji 15.6)
Najpierw zaktualizuj odwołania Nuget projektu, aby odwoływać się do najnowszego interfejsu API edytora:
Kliknij prawym przyciskiem myszy projekt i wybierz polecenie Zarządzaj pakietami Nuget.
W Menedżer pakietów Nuget wybierz kartę Aktualizacje, zaznacz pole wyboru Zaznacz wszystkie pakiety, a następnie wybierz pozycję Aktualizuj.
Procedura obsługi poleceń jest implementacją ICommandHandler<T>klasy , która obsługuje polecenie przez utworzenie wystąpienia elementu adornment.
Dodaj plik klasy i nadaj mu
KeyBindingCommandHandler
nazwę .Dodaj następujące dyrektywy using.
using Microsoft.VisualStudio.Commanding; using Microsoft.VisualStudio.Text.Editor; using Microsoft.VisualStudio.Text.Editor.Commanding.Commands; using Microsoft.VisualStudio.Utilities; using System.ComponentModel.Composition;
Klasa o nazwie KeyBindingCommandHandler powinna dziedziczyć z
ICommandHandler<TypeCharCommandArgs>
klasy i eksportować ją jako ICommandHandler:[Export(typeof(ICommandHandler))] [ContentType("text")] [Name("KeyBindingTest")] internal class KeyBindingCommandHandler : ICommandHandler<TypeCharCommandArgs>
Dodaj nazwę wyświetlaną programu obsługi poleceń:
public string DisplayName => "KeyBindingTest";
Zaimplementuj metodę
GetCommandState()
w następujący sposób. Ponieważ ta procedura obsługi poleceń obsługuje podstawowe polecenie TYPECHAR edytora, może delegować włączenie polecenia do edytora podstawowego.public CommandState GetCommandState(TypeCharCommandArgs args) { return CommandState.Unspecified; }
Zaimplementuj metodę
ExecuteCommand()
tak, aby dodaje fioletowe pole do widoku, jeśli znak plus (+) jest wpisany.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; }
- Skopiuj definicję warstwy adornment z pliku KeyBindingTestTextViewCreationListener.cs do pliku KeyBindingCommandHandler.cs, a następnie usuń plik 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;
Ustaw, że ozdoba jest wyświetlana w każdym wierszu
Oryginalna ozdoba pojawiła się na każdym znaku "a" w pliku tekstowym. Teraz, gdy zmieniliśmy kod, aby dodać ozdobę w odpowiedzi na + znak, dodaje ozdobę tylko w wierszu, w którym + jest wpisany znak. Możemy zmienić kod ozdoby, tak aby ozdoba pojawiała się po raz kolejny na każdym "a".
W pliku KeyBindingTest.cs zmień metodęCreateVisuals()
, aby iterować wszystkie wiersze w widoku, aby ozdobić znak "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);
}
}
}
}
}
}
Kompilowanie i testowanie kodu
Skompiluj rozwiązanie KeyBindingTest i uruchom je w wystąpieniu eksperymentalnym.
Utwórz lub otwórz plik tekstowy. Wpisz kilka wyrazów zawierających znak "a", a następnie wpisz + dowolne miejsce w widoku tekstowym.
Fioletowy kwadrat powinien być wyświetlany na każdym znaku "a" w pliku.