Ok, im Anschluss an gestern habe ich eine neue Ebene der Komplexität hinzugefügt. Wir haben noch eine theoretische Model-Klasse, ViewModel und View. Dieses Mal mein Modell ein Threading.Timer hat (Ausgewählt wurde speziell Timer-Rückrufe auf der „falschen“ Thread zu bekommen.INotifyPropertyChanged, ObservableCollection, Threads und MVVM
Das Modell ein ObservableCollection hat. Die Timer-Rückruf Elemente in die Sammlung ergänzt.
Das Ansichtsmodell einfach geht die Sammlung der Ansicht, das ein Listenfeld auf die Sammlung gebunden enthält.
das funktioniert nicht.
das Modell macht auch eine Zeichenfolge, die in dem gleichen Timer-Rückruf aktualisiert wird.
Auch dies wird über das Viewmodel offengelegt und an eine TextBox gebunden.
Das funktioniert.
Ich habe Hinweise in meinem googling gesehen, dass das Aktualisieren von Sammlungen INotifyCollectionChanged nicht wie erwartet funktioniert. Ich bekomme eine totale Implosion, nicht einmal eine Ausnahme, nur die sofortige Beendigung des Antrags.
So gibt es zwei Fragen:
One gestern auf unsere Diskussion bezieht. Ich verwende INotifyPropertyChanged und ObservableCollections in meinem Modell, weil sie die Ansicht sind, auf der die Ansicht funktioniert. Es macht immer noch Sinn, diese Mechanismen zu verwenden, um mein Ansichtsmodell zu benachrichtigen, oder was auch immer das zugrunde liegende Modell geändert hat. Wie gehe ich mit Updates um, die auf einem anderen Thread stattfinden?
Zweitens, was passiert, dass INotifyPropertyChanged mit der Bindung arbeiten? Ich binde eine Zeichenfolgeneigenschaft an eine DependencyProperty namens Text, also ist es das DependencyProperty-System, das meine Änderung zurück zum UI-Thread leitet? Edit: Und kann ich mich darauf verlassen, d. H. Tut es das, weil sie erwarten, dass ich mit ihr einen Cross-Thread sprich, oder ist es nur ein Fang, auf den ich mich nicht verlassen sollte?
Die ListBox ist über ItemsSource = "{Binding ObsCollection}" gebunden. Wenn das die Anwendung abstürzt. Eigentlich erst begann ich mit der Zeit, wenn das Modell erstellt wurde, das geschah, als das Datacontext des Fensters gesetzt wurde, so wäre es eigentlich Visual Studio bombardieren ...
Dank
10 Das ist cool, aber was ist der "richtige" Prozess, um aus MVVM-Perspektive damit umzugehen? Ein Thread in meinem Modell aktualisiert also eine Sammlung. Sollte mein Model jetzt über Disponenten Bescheid wissen? Das scheint falsch zu sein. Was bedeutet, dass mein ViewModel schwerer wird, um mit der korrekten Trennung zwischen Model und View fertig zu werden. Ist das sinnvoll? – Ian
Es gibt keinen "richtigen" Ansatz. Meine persönliche Präferenz besteht jedoch darin, eine einfache Schnittstelle zu erstellen, von der das ViewModel abhängt, IMarshalledInvoker, die eine einzige Methode zum Aufrufen einer Aktion in einem anderen Thread enthält. Wenn ich das ViewModel mit der View kuppel, erzeuge ich einen IMarshalledInvoker, der den Dispatcher unter den Covern verwendet. Mit diesem Muster kann ich noch Unit-Test, kann immer noch Designer-Unterstützung haben, d. H. Es ist gut MVVM ;-) – ColinE
Ah ok, die Dinge kommen jetzt zusammen. Komischerweise gibt es verschiedene Wissensbereiche, die sich auf eine Art und Weise beziehen, die ich nicht berücksichtigt habe. Erstens, wir wissen, dass die Erstellung einer Thread-sicheren Sammlung schwierig ist. Ich hatte das vergessen und die Assoziation nicht in meinem Kopf gemacht ... Im Wesentlichen füge ich nur einen Thread hinzu. Lustig, wie du vergisst, warum du Sachen machst. Ich denke, der Kern der Antwort besteht darin, Änderungen von mehreren Threads in einen einzigen Thread zu trichterieren. Es gibt also einen einzigen Kanal zwischen der Ansicht und dem Viewmodel ?? – Ian