Kürzlich wurde die VS2010-Erweiterung häufig im Visual Studio-Blog ( http://blogs.msdn.com/visualstudio/ ) erwähnt, daher wollte ich einen Blick in die Dokumentation werfen, um sie dort zu studieren Es gab keine vollständige Einführung in dieses Thema, also musste ich nach dem Inhalt der Vorlage in der VS-IDE und der Erklärung im Visual Studio-Blog suchen, während ich einige Codes kritzelte und mich auf eine Live-Übung vorbereitete Ich hatte das Gefühl, dass die mit dieser Vorlage erstellte Erweiterung zu einfach war. Ich habe zufällig gesehen, dass AxTool ( http://www.axtools.com/products-vs2010-extensions.php ) eine Code-Editor-Erweiterung hat, die auch ein VS ist Erweiterung, also bin ich dieser gefolgt und habe es Schritt für Schritt gemacht.
Um ein VS-Erweiterungsprojekt zu erstellen, müssen Sie zunächst das VS2010 SDK installieren, bei dem es sich derzeit um die Beta2-Version handelt. Sie können es hier herunterladen: http://go.microsoft.com/fwlink/?LinkID=165597 . Hier verwende ich das von der Text Adornment-Vorlage erstellte Editor-Projekt. Nun, ich werde nicht im Detail schreiben, wie Sie Ihr eigenes Erweiterungsprojekt mithilfe der Vorlage erstellen. Wenn Sie damit nicht vertraut sind, können Sie sich auf diesen Beitrag von Quan To beziehen - Erstellen und Veröffentlichen einer Erweiterung für Visual Studio 2010.
Nachdem das Projekt erstellt wurde, wird TextViewCreationListener automatisch generiert. Die IWpfTextViewCreationListener-Schnittstelle wird hier implementiert und das IWpfTextViewCreationListener-Objekt wird über MEF exportiert:
[TextViewRole("DOCUMENT")] [Export(typeof(IWpfTextViewCreationListener))] [ContentType("text")] interne versiegelte Klasse PETextViewCreationListener : IWpfTextViewCreationListener { void IWpfTextViewCreationListener.TextViewCreated(IWpfTextView textView) { //... } }
Auf diese Weise ruft VS zum richtigen Zeitpunkt die Methode IWpfTextViewCreationListener.TextViewCreated auf, um die Änderung des Textbearbeitungsstatus zu benachrichtigen.
Um Ihre eigene Symbolleiste schweben zu lassen, müssen Sie außerdem eine AdornmentLayerDefinition exportieren und die Anzeigeposition und Reihenfolge dieser Adornment-Ebene über das Order-Attribut anpassen:
[Name("QuickToolbarAdornmentLayer")] [Order(After = "Text")] [Export(typeof(AdornmentLayerDefinition))] public AdornmentLayerDefinition { get;
Das Namensattribut ist hier sehr wichtig, um unseren AdornmentLayer in zukünftigem Code zu erhalten:
this._adornmentLayer = this._textView.GetAdornmentLayer("QuickToolbarAdornmentLayer");
Gehen wir noch einen Schritt weiter und kehren wir zu IWpfTextViewCreationListener.TextViewCreated zurück. Hier können Sie eine IWpfTextView abrufen.
Dies ist das Ziel und die Darstellung aller Vorgänge. Darüber hinaus müssen die Ereignisse „Closed“, „LayoutChanged“, „MouseHovered“, „SelectionChanged“ und andere Ereignisse aufgehängt werden, um auf das Benutzerverhalten zu reagieren.
Da wir den Code über die Symbolleiste bedienen möchten, müssen wir IEditorOperationsFactoryService über MEF importieren:
[Import] internal IEditorOperationsFactoryService EditorOperationsFactoryService { get;
Auf diese Weise können IEditorOperations über IEditorOperationsFactoryService.GetEditorOperations(ITextView) in IWpfTextViewCreationListener.TextViewCreated abgerufen werden. Damit können Sie den Code bequem und schnell bearbeiten.
Als nächstes müssen wir die Symbolleistenschnittstelle implementieren. Ich werde nicht näher darauf eingehen. Erstellen Sie einfach ein UserControl und fügen Sie darin eine Symbolleiste ein. Wann und wo soll diese Symbolleiste angezeigt werden? Dies hängt vom SelectionChanged-Ereignis von IWpfTextView ab. Das oben erwähnte Ereignis wird hier verwendet.
Code
1 private void MayBeAdornmentShowCondition() 2 { 3 if (!this._textView.Selection.IsEmpty) 4 { 5 SnapshotPoint startPos = this._textView.Selection.Start.Position; 6 SnapshotPoint endPos = this._textView.Selection.End.Position; 7 IWpfTextViewLine textViewLineContainingBufferPosition = this._textView.GetTextViewLineContainingBufferPosition(startPos); 8 TextBounds CharacterBounds = textViewLineContainingBufferPosition.GetCharacterBounds(startPos); 9 TextBoundsbounds2 = this._textView.GetTextViewLineContainingBufferPosition(endPos);10 if (this._fromMouseHover)11 {12 this._mustHaveAdornmentDisplayed = true;13 }14 else15 {16 PELeftButtonMouseProcessor property = null;17 try18 {19 property = this._textView.Properties.GetProperty<PELeftButtonMouseProcessor>(typeof(PELeftButtonMouseProcessor));20 }21 Catch22 {23 }24 this._mustHaveAdornmentDisplayed = (property != null)25 && (property.IsLeftButtonDown26 || ((DateTime.Now - property.LastLeftButtonDownTime).TotalMilliseconds < 400.0));27 }28 if (this._mustHaveAdornmentDisplayed)29 {30 TextBounds SelectionBounds = !this._textView.Selection.IsReversed ?bounds2 :characterBounds;31 int offset = 7;32 double top =selectionBounds.Top + (!this._textView.Selection.IsReversed ? (offset + textViewLineContainingBufferPosition.Height) : (-offset - this ._adornmentUI.ActualHeight));33 if (top < 0.0)34 {35 top = 0.0;36 }37 double left = CharacterBounds.Left + ((bounds2.Left - CharacterBounds.Left) / 2.0);38 if ((left + this._adornmentUI.ActualWidth) > this._textView.ViewportWidth)39 {40 left = this._textView.ViewportWidth - this._adornmentUI.ActualWidth;41 }42 Canvas.SetTop(this._adornmentUI, top);43 Canvas.SetLeft( this._adornmentUI, left);44 long chars = 0L;45 try46 {47 chars = this._textView.Selection.SelectedSpans[0].Span.Length;48 }49 Catch50 {51 }52 this._adornmentUI.SetStatus(chars) ;53 this.RenderSelectionPopup();54 }55 }56 else57 {58 this._mustHaveAdornmentDisplayed = false;59 this._adornmentLayer.RemoveAdornmentsByTag(this._adornmentTag);60 }61 }62 63 private void RenderSelectionPopup()64 {65 if ( this._mustHaveAdornmentDisplayed)66 {67 IAdornmentLayerElement element = null;68 try69 {70 element = this._adornmentLayer.Elements.First<IAdornmentLayerElement>(71 (IAdornmentLayerElement ile) => ile.Tag.ToString() == this._adornmentTag); 72 }73 Catch (InvalidOperationException)74 {75 }76 if (element == null)77 {78 this._adornmentLayer.AddAdornment(this._textView.Selection.SelectedSpans[0], this._adornmentTag, this._adornmentUI);79 } 80 this._timer.Stop();81 this._timer.Start();82 }83 }84 85 private void Selection_SelectionChanged(object sender, EventArgs e)86 {87 this._fromMouseHover = false;88 this.MayBeAdornmentShowCondition(); 89}90
Dann ist zu beachten, dass Sie bei der Behandlung des Closed-Ereignisses von IWpfTextView daran denken müssen, alle Abschlussarbeiten wie dieses Ereignis abzubrechen.
semi.png(12,70 K)
25.01.2010 16:42:05
toolbar.png(15,64 K)
25.01.2010 16:42:05
Als nächstes kompilieren Sie das Projekt und packen VSIX. Die derzeit implementierten Hauptfunktionen sind:
1. Wenn Sie im Code-Editor einen Textabschnitt auswählen und die Maus in den Textbereich bewegen, „schwebt“ QuickToolbar halbtransparent neben dem Text.
2. Wenn sich die Maus in den QuickToolbar-Bereich bewegt, wird die QuickToolbar undurchsichtig und die Schaltflächen darauf reagieren auf Mausaktionen.
3. Derzeit unterstützte Operationen sind:
Schneiden
Kopie
Paste
Löschen
Einzug verkleinern
Einzug vergrößern
Kommentarcode (Kommentar)
Kommentar entfernen
usw.
Download- und Installationsmethoden für VSIX und Quellcode finden Sie im GCDN-Forum: [VS2010 Extension] Floating Toolbar ( http://gcdn.grapecity.com/showtopic-345.html )
Der Apostroph sein, der „Unmöglich“ in „Ich bin möglich“ verwandelte
-------------------------------------------------- --
WinkingZhangs Blog ( http://winkingzhang.cnblogs.com )
GCDN ( http://gcdn.grapecity.com/cs )