MVVM in der Praxis
Das Entwurfsmuster MVVM (Model-View-ViewModel) erfreut sich größter Beliebtheit bei Softwareentwicklern, die Clients auf Basis von XAML-Technologien wie WPF, Silverlight und/oder WP7 bauen. Die mächtigen Frameworks Prism und Caliburn.Micro bieten weit mehr als nur die Unterstützung zur Umsetzung des MVVM Design Patterns. Die Entkopplung der Komponenten per Dependency Injection oder Konzepte zur Kommunikation zwischen den Modulen sind nur einige unter vielen anderen Features. Allerdings ist die Einarbeitungszeit bei beiden Frameworks entsprechend hoch. Je nach Anforderungslage werden einige Funktionen diser umfangreichen Frameworks nicht benötigt. Da empfielt es sich, ein eher leichtgewichtigeres Framework, wie zum Beispiel das MVVM Light Toolkit von Galasoft zu wählen. Es bietet dem Entwickler u.a. eine Basisklassse für ViewModels, ein Messagingsystem zur Kommunikation zwischen ViewModels und ein paar weitere Helper Klassen. Ausserdem ist es für WPF, Silverlight und Windows Phone 7 verfügbar und neuerdings auch für Windows 8.
Wenn es um die reine Umsetzung von MVVM geht, sprich um die Kopplung zwischen einer View und dem dazugehörigen ViewModel, so kann man sehr einfach mit folgenden DLLs, die im Lieferumfang von Expression Blend zur Verfügung stehen, erweiterte Unterstützung erhalten. Folgende DLLs sind zu referenzieren:
[code language=“xml“]
System.Windows.Interactivity.dll
Microsoft.Expression.Interactions.dll
[/code]
Und die dazugehörigen Namespaces:
[code language=“xml“]
xmlns:i=“<a href=“http://schemas.microsoft.com/expression/2010/interactivity“>http://schemas.microsoft.com/expression/2010/interactivity</a>“
xmlns:ei=“<a href=“http://schemas.microsoft.com/expression/2010/interactions“>http://schemas.microsoft.com/expression/2010/interactions</a>“
[/code]
Über den ersten Namespace erhält man zum einen die Möglichkeit in XAML für beliebige Controls sogenannte EventTrigger zu definieren, die dann eine der folgenden Actions bzw. Behaviors auslösen können:
CallMethodAction
ChangePropertyAction
InvokeCommandBehavior
Mit diesen Erweiterungen kann man nun sehr komfortabel auf das ViewModel zugreifen. Im ersten Beispiel wird mit Hilfe eines EventTriggers eine beliebige Methode auf dem Targetobjekt aufgerufen. Die EventArgs des auslösenden Ereignisses werden dabei mitübertragen. Das TargetObjekt (=DataContext) ist beim Einsatz des MVVM Patterns stets an das ViewModel gebunden.
[code language=“xml“]
<!– View –>
<ListBox>
<i:Interaction.Triggers>
<i:EventTrigger EventName=“SelectionChanged“>
<ei:CallMethodAction MethodName=“DoSomething“ TargetObject=“{Binding}“/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ListBox>
[/code]
[code language=“csharp“]
// ViewModel:
public void DoSomething(object sender, SelectionChangedEventArgs e)
{ }
[/code]
Wichtig dabei ist, die Methode im View als public zu definieren. Im nächsten Beispiel sehen wir die Möglichkeit, ein im ViewModel definiertes Property direkt zu manipulieren:
[code language=“xml“]
<Button>
<i:Interaction.Triggers>
<i:EventTrigger EventName=”Click”>
<ei:ChangePropertyAction PropertyName=”MyViewModelProperty”
Value=”True” TargetObject=”{Binding}”/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
[/code]
Im letzten Beispiel ermöglicht InvokeCommandAction bei beliebigen Controls das Auslösen eines Commands und dabei die Übergabe eines beliebigen Parameters:
[code language=“xml“]
<TextBox x:Name=”inputBox”/>
<i:Interaction.Triggers>
<i:EventTrigger EventName=”TextChanged”>
<ei:InvokeCommandAction Command=”{Binding TextChangedCommand}”
CommandParameter=”{Binding ElementName=inputBox, Path=Text}”/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
[/code]
Mit Expression Blend kann man sogar ganz auf das Coden verzichten, in dem nicht nur der Entwickler sondern auch der UI-Designer die genannten Actions und Behaviors, die im Bereich Assets > Behaviors zu finden sind, einfach per Drag & Drop auf das gewünschte Control fallen lässt.
Zum Schluss noch ein sehr interessantes MVVM Framework auf Github: Claudron