ChildWindow, DialogResult und MVVM

Die Steuerung eines ChildWindow-Objektes in Silverlight wirft sehr schnell Fragen auf, wenn MVVM sauber eingesetzt werden soll. Wann ist die Eigenschaft DialogResult zu setzen und wer ist dafür verantwortlich, sind die ersten Fragen, die sich stellen.

Ansatz 1: Binding auf Eigenschaft DialogResult

Der erste Versuch liegt vermutlich darin, die Eigenschaft DialogResult des ChildWindow auf eine Eigenschaft des dahinter liegenden ViewModels zu binden. Dies wird jedoch fehl schlagen, da es sich dabei nicht um eine Dependency Property handelt. Ein Binding ist also nicht möglich. Dieser Weg scheitert hier. Eine Beschreibung dieser Eigenschaft findet sich im MSDN.

Ansatz 2: Attached Behavior

Eine funktionierende Lösung besteht darin, ein Attached Behavior zu implementieren. Dieses stellt eine Dependency Property zur Verfügung, welche auf einem ChildWindow an das dahinter liegende ViewModel gebunden werden kann. Das ViewModel selbst muss dafür eine entsprechende Eigenschaft zur Verfügung stellen.

public class DialogResultBehavior

{

    public static readonly DependencyProperty DialogResultProperty =

        DependencyProperty.RegisterAttached(

                "DialogResult", typeof(bool?), typeof(DialogResultBehavior), 

                new PropertyMetadata(DialogResultPropertyChanged)

        );

 

    private static void DialogResultPropertyChanged(

        DependencyObject dependencyObject,

        DependencyPropertyChangedEventArgs e)

    {

        var childWindow = dependencyObject as ChildWindow;

        if (childWindow != null)

            childWindow.DialogResult = e.NewValue as bool?;

    }

 

    public static bool? GetDialogResult(ChildWindow childWindow)

    {

        return childWindow.GetValue(DialogResultProperty) as bool?;

    }

 

    public static void SetDialogResult(ChildWindow childWindow, bool? value)

    {

        childWindow.SetValue(DialogResultProperty, value);

    }

}

Eingebunden wird dies im ChildWindow nun folgendermaßen:

<controls:ChildWindow x:Class="DevTyr.ChildWindow.MvvmDemo.Views.DateSelectionWindow"

           xmlns="schemas.microsoft.com/winfx/2006/xaml/presentation" 

           xmlns:x="schemas.microsoft.com/winfx/2006/xaml" 

           xmlns:beh="clr-namespace:DevTyr.ChildWindow.MvvmDemo.Behaviors"

           beh:DialogResultBehavior.DialogResult="{Binding DialogResult}">

           

           // Markup

           

</controls:ChildWindow>

In dieser Definition wird vorausgesetzt, dass das ViewModel eine Eigenschaft DialogResult bereit stellt. Diese wird durch das ViewModel mit dem korrekten Wert gesetzt. Im Normalfall geschieht dies durch an Schaltflächen gebundene Commands.

Das Ergebnis ist nun ein sauberer Weg, ein ChildWindow durch das im ViewModel implementierte Verhalten zu steuern. Wege á la Ereignishandler für das Click-Event, welche das MVVM-Pattern brechen, werden dadurch vermieden.

Veröffentlicht von Norbert Eder

Ich bin ein leidenschaftlicher Softwareentwickler. Mein Wissen und meine Gedanken teile ich nicht nur hier im Blog, sondern auch in Fachartikeln und Büchern.

Beteilige dich an der Unterhaltung

1 Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

  1. Hallo Norbert,

    genau so eine Hilfestellung wie hier habe ich verzweifelt gesucht. Allerdings ist mir nicht ganz klar wie ich nun in meinem ViewModel mit dem DialogResult arbeite. Kannst du evtl. deinen Artikel noch etwas erweitern bzw. ausführen?

    LG

Cookie-Einstellungen
Auf dieser Website werden Cookie verwendet. Diese werden für den Betrieb der Website benötigt oder helfen uns dabei, die Website zu verbessern.
Alle Cookies zulassen
Auswahl speichern
Individuelle Einstellungen
Individuelle Einstellungen
Dies ist eine Übersicht aller Cookies, die auf der Website verwendet werden. Sie haben die Möglichkeit, individuelle Cookie-Einstellungen vorzunehmen. Geben Sie einzelnen Cookies oder ganzen Gruppen Ihre Einwilligung. Essentielle Cookies lassen sich nicht deaktivieren.
Speichern
Abbrechen
Essenziell (1)
Essenzielle Cookies werden für die grundlegende Funktionalität der Website benötigt.
Cookies anzeigen