2016-05-06 14 views
0

Diese Frage bezieht sich auf eine WPF-Anwendung, die auf PRISM 5.0 und dem MVVM-Muster basiert.MVVM-Entwurf: Blockieren von MessageBox in ViewModel

Manchmal, wenn Benutzer Entscheidungen treffen, die unerwünschte oder negative Konsequenzen haben können, ist es sehr üblich, den Benutzer zu fragen, ob er wirklich weitermachen und fortfahren möchte.

Zum Beispiel: Eine übliche Art und Weise, wird der Benutzer mit einem messagebox fragen, ob er wirklich Daten löschen will, das kann nicht nach dem Löschen wiederhergestellt werden.

Das Problem ist: Wenn ich die MessageBox innerhalb des Ansichtsmodell nennen, das Ansichtsmodell wird untestable von außen.

//BAD! 
public class ViewModel 
{ 
    public Boolean Delete() 
    { 
     //Blocking and therefore untestable in automatic UnitTests 
     MsgBoxResult result = MsgBox.Show("Do you really want to delete?"); 

     if (result == yes) {//Do stuff that deletes data here;} 

    } 
} 

Eine Möglichkeit wäre, die Frage in einer anderen privaten Methode zu stellen, dass die Öffentlichkeit Methode

//BETTER, BUT OK? 
public class ViewModel 
{ 
    private void OnDeleteAction 
    { 
     MsgBoxResult result = MsgBox.Show("Do you really want to delete?"); 
     if (result == yes) {Delete();} 
    } 

    public Boolean Delete() 
    { 
     //Testable from the outside again, because no blocking question 

     //Do stuff that deletes data here 
    } 

Meine Frage stellt: Ist dies ist ein guter Weg, oder gibt es eine elegante Möglichkeit, den Benutzer in einem ViewModel zu fragen? Können Sie mir einen Hinweis oder Link geben, was ist das Beste für PRISM 5.0?

Ich weiß, dass eine Faustregel ist, keine UI-Elemente im ViewModel zu verwenden, aber ich sehe keine Alternative zu einer blockierenden MessageBox oder etwas anderem, das den Prozess blockiert, bevor Sie fortfahren.

Vielen Dank für Hinweise!

+1

Gemäß meinem Verständnis sollte man jede nicht schreiben verwandten Code im View-Modell und Logik-bezogenen Code in der Ansichtsseite anzeigen. So können Sie das Meldungsfeld im Ansichtscode hinter und auf der Grundlage der Benutzerauswahl öffnen, die Sie in der Sichtmodellklasse Ihre Löschmethode aufgerufen haben. –

+0

'öffentliche Schnittstelle MuhMessageBox {bool AreYouCrazy (Zeichenfolge Nachricht); } ' – Will

Antwort

1

Prisma Interaktivität ist der Weg, hier zu gehen. Auf diese Weise können Sie Bestätigungen und Benachrichtigungen erstellen und benutzerdefinierte Dialoge erstellen, die gut mit dem MVVM-Muster funktionieren. Ich verwende sie erfolgreich in meinen Prism-Anwendungen.

Hier sind einige Links zu einigen Code in den Repo Prism auf GitHub:

Notification Request

Confirmation Request

Custom Content

Custom Request

+0

Danke, ich werde es durchlesen und später wiederkommen – Michael

+0

Beide Antworten, von Sebastian Schulz und R.Richards, waren tolle Hilfen, aber ich akzeptiere diese Antwort gegenüber den anderen, weil das von R.Richards zur Verfügung gestellte Codebeispiel mir am meisten geholfen hat . Wenn Sie keine Ahnung haben, wo Sie anfangen sollen, schauen Sie sich das Beispiel an, es ist enorm und es macht viele Dinge klar, wenn es um WPF, MVVM und Interaktivität geht. Ich danke dir sehr. – Michael

+0

Link ist veraltet. Gibt es einen aktualisierten? – Flynn1179

3

Es gibt zwei bekannte Alternativen, die die Kopplung zwischen View und ViewModel reduzieren können: Verwenden eines Interaktionsdienstes und Auslösen von Interaktionsanforderungen. Beide sind sehr gut erklärt here; Vielleicht möchten Sie einen Blick darauf werfen.

Die allgemeine Idee besteht darin, dass Sie abstrahieren, wie asynchrone Interaktionen ausgeführt werden und mit ereignisbasierter Logik arbeiten, während das ViewModel gleichzeitig ausdrücken kann, dass es als Teil einer Operation mit dem Benutzer interagieren möchte ; Das Ergebnis ist, dass Sie diese Interaktion dokumentieren und testen können.

+0

Danke, ich werde es durchlesen und später wieder kommen – Michael

+0

Nochmals vielen Dank, Sebastian. Ihr Hinweis war eine große Hilfe, aber in diesem Fall akzeptiere ich R. Richards Antwort als die beste Hilfe, wegen seines großartigen Codebeispiels. Siehe meinen Kommentar unter der angenommenen Antwort. – Michael