C #, WPF, MVVM und INotifyPropertyChanged

8

Ich bin verwirrt; Ich dachte, ich hätte INotifyPropertyChanged verstanden.

Ich habe eine kleine WPF-App mit einer Front-MainWindow-Klasse, einem Viewmodel in der Mitte und einem Modell auf der Rückseite.

Das Modell in meinem Fall ist die Simulator-Klasse.

Das SimulatorViewModel ist nahezu transparent und verbindet nur die Eigenschaften zwischen MainWindow und Simulator.

Simulator implementiert INotifyPropertyChanged und jeder Eigenschaftensetter in Simulator ruft die RaisePropertyChanged-Methode auf:

%Vor%

In der XAML habe ich eine TextBox mit Binding wie folgt:

%Vor%

und der DataContext ist das SimulatorViewModel (aber siehe meinen Kommentar zum Ändern des DataContext in das Modell)

Das ViewModel übergibt die Eigenschaften einfach durch:

%Vor%

Programmatische Aktualisierungen der Eigenschaft SerialNumber in Simulator werden nicht an die Benutzeroberfläche weitergegeben, obwohl seltsamerweise der Anfangswert, der im Simulator-Konstruktor festgelegt wurde, dorthin gelangt.

Wenn ich den SerialNumber-Setter im Simulator unterbricht und RaisePropertyChanged folge, finde ich, dass PropertyChanged null ist und sich das Ereignis nicht auf die GUI ausbreitet.

Was mich zu einigen Fragen führt:

  1. Was genau sollte das PropertyChanged-Ereignis einbinden? Ich möchte genauer sein als nur "WPF". Was ist die Verknüpfung zwischen diesem Ereignis und der Binding-Anweisung in der XAML?

  2. Warum erreicht der anfängliche Eigenschaftswert beim Start die Benutzeroberfläche, nicht aber später?

  3. Habe ich recht, wenn Simulator (das Modell) INotifyPropertyChanged implementiert, oder sollte das ViewModel das tun? Wenn das ViewModel das tut, dann lösen programmatische Änderungen im Modell nicht PropertyChanged aus, daher bin ich bei dem korrekten Muster nicht klar. Ich weiß, dass mein ViewModel praktisch überflüssig ist, aber das liegt an der Einfachheit des Projekts; Eine komplexere würde das ViewModel-Konzept härter arbeiten lassen. Mein Verständnis ist, dass das ViewModel der Ort ist, an den meine Komponententests angeschlossen werden.

Alan 11.02.2011, 10:25
quelle

2 Antworten

7
  1. Das Problem ist, dass Sie PropertyChanged in Ihrem Modell erhöhen, Ihre Ansicht jedoch an ViewModel gebunden ist. Daher abonniert Ihre View nur ViewModel-Ereignisse (nicht die von Model). Aus diesem Grund wird die Textbox nicht aktualisiert, da sie nie PropertyChanged -Ereignis empfängt. Eine der möglichen Lösungen besteht darin, in ViewModel für Model PropertyChanged -Ereignisse anzuhören und dasselbe Ereignis in ViewModel entsprechend zu erhöhen.

  2. Der Anfangswert wird weitergegeben, weil Ihre Setter / Getter in ViewModel korrekt sind, das Problem liegt in Ereignissen.

  3. Ja, Sie haben Recht (siehe meine # 1), Sie sollten PropertyChanged auf Ihrem ViewModel erhöhen, weil View daran gebunden ist. Diese Ereignisse werden nicht automatisch nach Änderungen in Model ausgelöst. Daher sollten Sie in ViewModel auf Model.PropertyChanged warten.

Einfachste schmutzige Lösung, um die Idee zu verstehen:

%Vor%     
Snowbear 11.02.2011, 11:11
quelle
1
  1. Stellen Sie immer sicher, dass die Instanz der Klasse, die als Datenkontext festgelegt wurde, INotifyPropertyChanged
  2. implementieren sollte
  3. In Ihrem Fall implementiert Simulator INotifyPropertyChanged, aber SimulatorViewModel wird als DataContext festgelegt. In diesem Fall wird die Benutzeroberfläche nur dann erkannt, wenn Änderungen im SimulatorViewModel, aber nicht im Simulator vorhanden sind.

Was Sie tun können, ist Folgendes:

Sie können einige Ereignisse oder Delegaten in der Simulator-Klasse verfügbar machen und einige Methoden in der SimulatorViewModel-Klasse haken. Wenn sich dann Werte in der Simulator-Klasse ändern, rufen Sie das Ereignis oder den Delegaten auf, der Execute on SimulatorViewModel abruft. Jetzt können Sie die aktualisierten Werte vom Simulator abrufen und die Eigenschaften in SimulatorViewModel aktualisieren. Stellen Sie sicher, dass Sie unterschiedliche Eigenschaften in der Klasse

verwenden     
Kumareshan 16.10.2013 01:58
quelle