Trigger oder VisualStateManager ?

Mit Silverlight hat Microsoft vor einigen Jahren den VisualStateManger in die WPF eingefügt. Mit diesem soll es einfacher sein Vorlagen ( Templates ) zu definieren und das Aussehen anhand verschiedener Zustände zu definieren. Für mich stellte sich vor kurzem die Frage ob es klüger ist mit Triggern zu arbeiten oder auf den VSM zu setzen.

Beim Erzeugen der Menükomponente für das MAF habe ich bisher lediglich auf Trigger gesetzt und habe das Aussehen der einzelnen TreeViewItems anhand von Eigenschaft wie “IsPressed” und dergleichen von Triggern überwachen lassen. Vor kurzem stieß ich dann in einem Artikel auf den VSM und es kam mir so vor als wäre diese Art der Implementierung etwas sauberer und einfacher. Betrachtet man folgendes Codesegment so fällt sofort auf, dass man den Hintergrund der Trigger kaum versteht bzw. auf welchen Zustand des Controls er sich beziehen soll.

Im Gegenzug dazu, bietet der VSM nicht nur die Möglichkeit verschiedene Zustände zu definieren, sondern auch wie die Übergänge von Zustand A nach B auszusehen hat. Diese Übergänge können via Storyboards festgelegt werden.

Trigger sind jedoch alles andere als eine überholte Methode. Sie werden immer noch eingesetzt um das Aussehen von Steuerelementen zu definieren die keine passenden Eigenschaften besitzen um mit dem VSM zu korrespondieren. Der normale Button hat beispielsweise eine Eigenschaft “IsDefault” zu der es keinen korrespondierenden Zustand gibt.

 

 

MAF – Menükomponente

Derzeit arbeite ich intensiv am Fortschritt eines Frameworks ( MAF – Modular Application Framework ) zur leichteren Gestaltung von WPF Anwendungen die mit PRISM modular zusammengestellt werden. Einerseits will ich dadurch meine WPF und PRISM Kenntnisse vertiefen aber auch eine Möglichkeit schaffen um zukünftig schneller Oberflächen zu erstellen.

Die erste Station zur Erreichung dieses Ziels ist eine Komponente, die die Navigation innerhalb der Anwendung möglichst leicht gestaltet. Die Kombination aus einem Tab und mehreren TreeViews soll dazu beitragen die wichtigsten Optionen entweder auf der linken oder der rechten Seite auszurichten und schnell griffbereit zu haben. Der Stil der Anwendung wird dabei einheitlich bleiben, jedoch vollkommen austauschbar sein.

Der erste Entwurf aus Photoshop und wie es derzeit innerhalb der Anwendung aussieht kann nachfolgend begutachtet werden. Es steht noch etwas Arbeit bevor, besonders was die Einbindung der Icons innerhalb der Schaltflächen angeht. Problem wird nämlich sein diese beim überfliegen anders anzufärben.

Vorschau MenuKomponente

Telerik ZipLibrary & DotNetZip

Fazit der letzten zwei Tage. Die ZipLibrary von Telerik ist umständlich und schlecht dokumentiert. Ganz im Gegenteil zur DotNetZip Library, welche sehr einfach in der Handhabung, mächtig in der Anwendung ( sogar LINQ support! ) und gut dokumentiert ist. Hätte ich das vorher gewußt, hätte ich viele Arbeitsstunden die ich in die Telerik Library investiert habe sparen können. Aber man wächst ja auch mit den Erfahrungen.

Anforderung war bei mir, dass Material, welches in meiner SV hochgeladen werden kann, automatisch mit dem Zipformat gepackt wird. Außerdem konnte ich so die Funktionalität abdecken, dass mit einem “MaterialItem” ( bestehend aus Titel, Beschreibung und einer Datei ) auch mehrere Dateien hinterlegt werden können. Nachteil an diesem Vorgehen ist natürlich, dass man erst das komplette Zipfile runterladen muss bevor man auf einzelne Dateien Zugriff hat. Aber es ist sicherlich sowieso Sinnvoll eine Obergrenze für Dateigrößen festzulegen.

Anbei ein Ausschnitt meiner Implementierung mit der DotNetZip Library um zu demonstrieren wie einfach es letzten Endes doch war. ( this.DateiBytes ist dabei das Bytefeld eines Materialitems )

Sieht im Endeffekt dann in der GUI bisher so aus :

 

Telerik Drag & Drop in SV eingebaut

Seit einer Woche habe ich nun mit dem Drag & Drop “Framework” von Telerik gekämpft. Ganz einfach war es nicht, denn die Möglichkeit dieses in einer MVVM Umgebung einzusetzen ist weder vorgegeben noch ganz einfach. Hinzu kam für mich das Problem, dass es sich scheinbar mit dem PRISM Framework etwas anders verhält als in einer gewöhnlichen Anwendung.

Glücklicherweise konnte ich im Communityforum von Telerik ( Beitrag ) einige gute Hinweise und Ideen sammeln, wie sich die D&D Funktion in einer MVVM Architektur umsetzen lässt.

Die Anforderung selbst war recht einfach von der Idee her. Es sollte die Möglichkeit geben, Elemente aus einer Listbox ( die auf Anforderung von der Seite aufklappt ) in ein Gridcontrol per Drag & Drop reinzuziehen. Beachtet werden musste dabei natürlich, dass alles über Commands gesteuert wird. Die Recherche im Forum von Telerik hat mich darauf gebracht, dass man eine Behaviorklasse für das Listbox Element schreiben könnte, die beim attachen an das Control dieses dann beim RadDragAndDropManager von Telerik registriert und die Events an attached Commands bindet. Anbei ein kleines Beispiel für ein Objekt vom Typ “ItemsControl” ( Denn eine Listbox ist von diesem Typ ) :

Ich speichere die ursprüngliche Dicke des Randes sowie die Farbe übrigens, da ich beim Ziehen über ein gültiges Element, eine Highlightfarbe setze um dem Benutzer zu verdeutlichen, dass das Element dort fallen gelassen werden kann. Nun wollen wir allerdings zunächst den Handler mit unserer Listbox verknüpfen. Dazu benötigen wir im Handler allerdings auch noch Commands, sowie die Eventhandler :

Das entspricht natürlich keiner vollständigen Implementierung. Wichtig ist an dieser Stelle eigentlich nur die Idee. Den Download der vollständigen Klassen findest du am Schluss des Beitrags.  Es folgt nun die Einbettung des Behaviors im XAML Designcode :

Damit das ganz funktionieren kann muss man natürlich auch die einzelnen Items mit einer D&D Funktionalität ausstatten. Das kann recht einfach über das ItemTemplate gemacht werden.

Da dies lediglich einige Codeausschnitte sind, die ein bisschen die Idee hinter der Umsetzung erklären sollen, kannst du hier ( Dragdrop Klassen ) die vollständigen Klassen runterladen.

Bei mir schaut das ganze nun so aus :)

 

WPF: Images in fremden Assemblies über XAML ansteuern

Derzeit überlege ich, wie ich am effektivsten Ressourcen in meiner Studentenverwaltung hinterlegen kann. Ich persönlich finde es unsauber, wenn die Anwendung mit vielen Verzeichnissen ausgeliefert wird und die Dateien darin öffentlich sichtbar sind.

Build Properties für Images

Glücklicherweise gibt es die Möglichkeit sämtliche Ressourcen auch in Assemblies einzubetten. Bilder beispielsweise können einfach mit dem Buildattribut “Resource” deklariert werden. Dabei sollte dann natürlich darauf geachtet werden, dass bei “In Ausgabeverzeichnis kopieren” der Wert “Nicht kopieren” angegeben ist.

Aus dem XAML Code eines WPF Fensters/Controls lassen sich diese Bilder nun auch recht einfach ansteuern. Es wird lediglich ein Verweis auf die Assembly, in der sich das Bild befindet, benötigt. Dazu gibt es in WPF sogenannte “Pack URI’s“. Mehr dazu kann man auch Hier im MSDN erfahren.

Beispiel :

Für mein Projekt bedeutet das, dass ich eine eigene austauschbare Assembly nur für Bilder und Icons einsetzen werde, die sowohl ich WPF Applikationen, als auch in Webanwendungen zum Einsatz kommen kann. Das Laden von Bildern über C# Code ist übrigens ebenso möglich.

 

Das bin ich

Michael Morbach kleinÜber die Jahre habe ich mich auf Microsoft .NET C# spezialisiert und finde dort aktuell besonders die Entwicklung von modularen und verteilten Anwendungen mit WPF, WCF und PRISM interessant. Die modulare Aufteilung von Anwendungen in kleine funktionale Komponenten ist aus meiner Sicht der Inbegriff von moderner Softwarearchitektur.

Netzwerke


profile for KroaX at Stack Overflow, Q&A for professional and enthusiast programmers