Im neuen Behavior SDK für Windows Phone 8.1 lassen sich Events über einen InvokeActionCommand zu einem beliebigen ICommand im ViewModel umleiten. Dadurch lässt sich eine saubere Implementierung im Sinne des MVVM Entwurfsmusters erreichen und es entsteht weniger Code in der CodeBehind-Datei. Auch für Windows Phone 8 Silverlight Anwendungen gibt es dafür eine Lösung: Mit dem Expression Blend SDK und dem System.Windows.Interactivity Namespace lassen sich ebenfalls Commands über Events ansprechen. Wie das funktioniert, wird in diesem Artikel gezeigt.

1. Blend SDK installieren

Um die Interactivity-Klasse verwenden zu können, wird das Expression Blend SDK von Microsoft benötigt. Dieses ist bereits in der Installation von Blend für Visual Studio 2013 enthalten. Alternativ ist das SDK separat hier erhältlich.

 2. Verweis zum Projekt hinzufügen

Nachdem das Blend SDK installiert wude, kann der System.Windows.Interactivity Namespace über den Verweis-Manager dem Projekt hinzugefügt werden.

3. EventTrigger in XAML hinzufügen

Über einen EventTrigger kann ein Event abgefangen und anschließend an ein ICommand innerhalb des ViewModels umgeleitet werden. In folgendem Beispiel soll das „Hold“-Event eines Rectangles über ein ICommand im ViewModel behandelt werden.

1
2
3
<Grid x:Name="LayoutRoot" Background="Transparent" DataContext="{Binding}">
    <Rectangle Fill="{Binding RectColor}" Hold="Rect_Hold" />
</Grid>

Hierzu wird der Interactivity-Namespace im XAML bekannt gemacht (Zeile 16) und innerhalb des Rectangle-Elements ein EventTrigger definiert, der auf das Event mit dem Namen „Hold“ reagiert. Innerhalb der InvokeCommandAction wird über das Binding der gewünschte Command eingebunden. Es ist ebenfalls möglich, über das Attribut CommandParameter einen beliebigen Parameter an das ICommand zu übergeben.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<phone:PhoneApplicationPage
    x:Class="EventsToCommands.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait"
    Orientation="Portrait"
    shell:SystemTray.IsVisible="True"
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity">

    <Grid x:Name="LayoutRoot" Background="Transparent" DataContext="{Binding}">
        <Rectangle Fill="{Binding RectColor}">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="Hold">
                    <i:InvokeCommandAction
                        Command="{Binding DemoCommand}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Rectangle>
    </Grid>

</phone:PhoneApplicationPage>

 4. ICommand im ViewModel definieren

Innerhalb des ViewModels muss der Command definiert sein (hier DemoCommand). Hier wird ein DelegateCommand verwendet, welcher die ICommand Schnittstelle implementiert. In dem dargestellten Beispielcode wird die Farbe des Rectangles geändert, wenn das Hold-Ereigniss eintritt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class MainViewModel : BindableBase
{
    // Feld für die Rectangle Farbe
    private SolidColorBrush rectColor;

    public MainViewModel()
    {
        this.rectColor = new SolidColorBrush(Colors.Blue);
        this.DemoCommand = new DelegateCommand(this.DemoCommandAction);
    }

    // Command der beim Hold-Event ausgeführt wird
    public DelegateCommand DemoCommand { get; set; }

    // Property für die Rectangle Farbe
    public SolidColorBrush RectColor
    {
        get { return this.rectColor; }
        set { this.SetProperty(ref this.rectColor, value); }
    }

    // Wird ausgeführt, wenn der Command aufgerufen wird
    private void DemoCommandAction(object obj)
    {
        // Farbe des Rectangles ändern
        this.RectColor = new SolidColorBrush(Colors.Red);
    }
}

Zusammenfassung

In diesem Artikel wurde gezeigt, wie der Interactivity-Namespace des Expression Blend SDKs eingesetzt werden kann, um in Windows Phone 8 Silverlight Anwendungen Events zu ICommands umzuleiten. Dieses wird mit dem Behavior SDK für Windows Phone 8.1 ersetzt, ist aber für ältere Windows Phone Silverlight Anwendungen sehr nützlich.

Beispielprojekt

Das Beispielprojekt ist hier auf GitHub zu finden.