Tuningalarm – Visual Studio 2010 aufgemotzt (Teil 2)
Kommentare

Damit aber nicht genug. In Listing 1 erhält man außerdem die Möglichkeit, bereits bestehende Erweiterungen zu nutzen, indem im Bereich REFERENCES Verweise auf bereits installierte Erweiterungen (Auswahl

Damit aber nicht genug. In Listing 1 erhält man außerdem die Möglichkeit, bereits bestehende Erweiterungen zu nutzen, indem im Bereich REFERENCES Verweise auf bereits installierte Erweiterungen (Auswahl per Name) oder auf Erweiterungen, die sich im Dateisystem befinden, (.vsix-Dateien) gesetzt werden. Im Bereich CONTENT lassen sich die verschiedenen Projekttypen miteinander kombinieren. Eine Auswahlliste bietet als Content Type unter anderem Visual Studio Packages, MEF-Komponenten (z. B. Adornments) sowie Projektvorlagen und einiges mehr an. Ein existierendes Projekt lässt sich nun wahlweise (sofern existent) aus der aktuellen Solution oder aber über die Angabe einer Projektdatei (bzw. auch als einzelne Datei) hinzufügen.

Adornments – die Factory-Klasse

Ein weiterer essenzieller Bestandteil eines MEF-Projekts ist die so genannte Factory-Klasse. Die Factory implementiert und exportiert die IWpfTextViewCreationListener-Schnittstelle. Das ermöglicht eine Benachrichtigung der Factory-Klasse, wenn neue Text-Views erstellt wurden. In diesem Fall wird die TextViewCreated-Methode (deren Signatur in IWpfTextViewCreationListener zu finden ist) aufgerufen. Zudem wird in der Factory-Klasse mittels des ContentType-Atttributs festgelegt, an welcher Art von Text-Views unsere Schnittstelle interessiert ist. Listing 2 demonstriert die Anwendung der beiden Attribute auf eine Klasse, die IWpfTextViewCreationListener implementiert.

 [Export(typeof(IWpfTextViewCreationListener))]
    [ContentType("text")]
    [TextViewRole(PredefinedTextViewRoles.Document)]
    internal sealed class SearchAdornmentFactory : IWpfTextViewCreationListener
    {
      //...
    }  

Die Factory erfüllt aber noch eine weitere wichtige Funktion: Sie erstellt eine neue Layer-Definition und exportiert auch diese. Wie bereits vorher erwähnt, sind Editor-Adornments in Schichten aufgebaut, besitzen also einen Z-Index und können entsprechend über- oder untereinander platziert werden. Über die Layer-Definition der Factory legen wir mittels geeigneter Attribute fest, was wir exportieren (Export), den Namen unseres Layers (Name) und dessen Reihenfolge (Order). Diese Attribute werden allesamt auf ein zu deklarierendes Objekt der Klasse AdornmentLayerDefinition angewandt (Listing 3).

        [Export(typeof(AdornmentLayerDefinition))]
        [Name("SearchAdornment")]
        [Order(After = PredefinedAdornmentLayers.Selection, Before = PredefinedAdornmentLayers.Text)]
        [TextViewRole(PredefinedTextViewRoles.Document)]
        public AdornmentLayerDefinition editorAdornmentLayer = null;  

Daneben erstellt die Factory in der TextViewCreated-Methode noch ein so genanntes Managerobjekt, das die eigentliche Funktionalität des Adornments beinhaltet. Die zugehörige Klasse ist bei der Erstellung eines Adornments bereits automatisch erstellt worden und trägt den Namen des Projekts. Diese Klasse enthält einen Konstruktor, der ein Objekt vom Typ IWpfTextView als Parameter übernimmt. Die Factory-Klasse wird bei der Erstellung eines Editor-Adornment-Projekts ebenfalls automatisch generiert und trägt standardmäßig den Namen des Projekts sowie den Suffix Factory.

Das eigentliche Adornment

Visual Studio 2010 generiert neben der Konfigurationsdatei und der Factory-Klasse auch die Managerklasse. Diese enthält die eigentliche Funktionalität des Adornments, d. h. grafische Hervorhebung einzelner Textbestandteile (wie im Standardbeispiel zu sehen) etc. Damit die Klasse (oder besser ein Objekt vom Typ der Managerklasse) überhaupt Zugang zum Codeeditor erhält, benötigt sie die folgenden grundlegenden Informationen:

  • Die aktuelle Ebene (engl. Layer, vom Typ IAdornmentLayer)
  • Die aktuelle Text-View (vom Typ IWpfTextView)

Diese beiden Informationen sind bereits zu Beginn in der Klasse als Member-Variablen enthalten. Daneben findet sich hier der Konstruktor, der von der Factory in TextViewCreated aufgerufen wird, aber auch die Methode OnLayoutChanged, die nichts anderes macht, als bei jeder Änderung der Text-View für jede Zeile (ITextViewLine) die Methode CreateVisuals aufzurufen (Listing 4).

private void OnLayoutChanged(object sender, TextViewLayoutChangedEventArgs e)
{
foreach (ITextViewLine line in e.NewOrReformattedLines)
   	{
       this.CreateVisuals(line);
}
}  

In CreateVisuals findet die ganze Logik statt, das heißt:

  1. Die Erstellung der grafischen Komponenten des Adornments bzw. das eigentliche Adornment
  2. Die Zuweisung des Adornments zum bereits vorher erwähnten Layer
Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -