2011-01-05 13 views
1

Ich habe ein paar Fragen zum Erstellen von WPF MVVM-Anwendungen.WPF MVVM-Anwendung - ICollectionView/Threading/Allgemeine Fragen

1) Ich verwende ICollectionView-Objekte für datengebundene Steuerelemente wie ListView und ComboBox. Ich fand, dass dies der einfachste Weg war, Zugriff auf das ausgewählte Element dieser Steuerelemente zu erhalten. Was ist der beste Weg, um den Inhalt von ICollectionView zu ersetzen? Derzeit ist es wie so ich tue:

private ICollectionView _files; 

public ICollectionView Files { 
    get { return _files; } 
} 

void _service_GetFilesCompleted(IList<SomeFile> files) { 
    this.IsProcessing = false; 
    _files = CollectionViewSource.GetDefaultView(files); 
    _files.CurrentChanged += new EventHandler(FileSelectionChanged); 
    OnPropertyChanged("Files"); 
} 

ich nicht wusste, ob es notwendig war, den Handler jedes Mal, wenn ich die Liste der Dateien aktualisieren wieder zu befestigen?

2) Jetzt wo ich meinen Kopf habe, fange ich an, das MVVM-Muster zu mögen. Ein Konzept, über das ich mir nicht ganz sicher bin, ist, wie man Benachrichtigungen an die Ansicht zurücksendet. Momentan mache ich das, indem ich an Eigenschaften in meinem ViewModel binde. Im obigen Code habe ich beispielsweise eine "IsProcessing" -Eigenschaft, mit der ich feststellen kann, ob eine ProgressBar angezeigt werden soll. Ist das der empfohlene Ansatz?

3) Im Anschluss an 2) - es scheint keine standardmäßige Möglichkeit zu geben, Ausnahmen in einer MVVM-Anwendung zu behandeln. Ein Gedanke, den ich hatte, war eine Methode für meine ViewModel-Basisklasse, die Ausnahmen behandelt. Ich könnte dann einen IMessagingService injizieren, der für das Weiterleiten von Fehlermeldungen verantwortlich war. Eine konkrete Implementierung könnte MessageBox verwenden.

4) Ich habe ein paar Aufgaben, die ich asynchron ausführen möchte. Anstatt diese Logik direkt in meinem Service hinzuzufügen, habe ich einen Decorator-Service erstellt, der die zugrunde liegenden Servicemethoden für einen neuen Thread ausführt. Es bietet eine Reihe von Ereignissen, die mein ViewModel dann abonnieren kann. Ich habe den folgenden Code aufgelistet. Ich verstehe, dass Background eine sicherere Option ist aber nicht wissen, ob es für den Betrieb mehrere asynchrone Aufgaben auf einmal geeignet war ?:

public void BeginGetFiles() 
    { 
     ThreadStart thread =() => { 
      var result = _serviceClient.GetUserFiles(username, password); 
      GetFilesCompleted(result.Files); 
     }; 

     new Thread(thread).Start(); 
    } 

Schließlich habe ich erkennen, dass es eine Reihe von MVVM Projekte Frameworks, die einige von ihnen behandeln Anforderungen. Ich möchte jedoch verstehen, wie man das oben genannte unter Verwendung der eingebauten Funktionalität erreicht.

Dank

Antwort

1

Wenn Sie Listviews und Comboboxen, sollten Sie wirklich eine ObservableCollection<> in Betracht ziehen, um diese Kontrollen zu binden. Durch das Hinzufügen und Entfernen von Elementen aus der Sammlung wird das Steuerelement, das die Eigenschaft geändert hat, automatisch benachrichtigt.

Wenn Sie Hintergrundverarbeitung durchführen, können Sie den BackgroundWorker oder DispatcherTimer anzeigen, um Aktualisierungen der Benutzeroberfläche zu behandeln. Beide können auf den UI-Thread angewendet werden und können Thread-sicher sein.

+0

Ich muss nie einzelne Elemente aus der Sammlung hinzufügen/entfernen; Die Sammlung wird immer ersetzt. Auch ICollectionView schien der einfachste Weg, um das aktuelle Objekt aus einem ListView zu bekommen - es sei denn, Sie können eine Alternative vorschlagen. Ja, ich kenne BackgroundWorker - bitte beachten Sie meine Frage zu mehreren Aufgaben. –

0

Um das ausgewählte Element aus einem Kombinationsfeld abzurufen, legen Sie ein INotifyCollectionChanged-Objekt wie ObservableCollection offen und binden es an die itemsource. Erstellen Sie dann eine andere Eigenschaft für das aktuelle Element und die Bindung ComboBox.SelectedItem (oder ComboBox.SelectedValue falls erforderlich) es. Sie müssen die Auswahl beim Aktualisieren der Sammlung verwalten.

Auf den ersten Blick scheint ICollectionView wie die offensichtliche Wahl, aber die WPF-Implementierung zwingt wirklich Ihre Hand auf einige Threading-Code, dass Sie wirklich nicht gestört werden sollte.

Ich habe kürzlich ICollectionView und CollectionViewSource (zum Filtern) verwendet und bin frustriert darüber, wie viele Dispatcher-Probleme sich eingeschlichen haben. Heute werde ich wahrscheinlich zu der oben beschriebenen Methode zurückkehren.