2010-12-14 5 views
3

Ich verwende MVVM in WPF in C# .NET. Sagen wir, ich habe folgendes Beispiel Modell:Wie wird die List-Eigenschaft eines Objekts in WPF bevorzugt?

public class Dealer 
{ 
    public string Name { get; set; } 
    public List<Car> Cars { get; set; } 
} 

public class Car 
{ 
    public string Make { get; set; } 
    public string Model { get; set; } 
} 

Aus meiner Sicht habe ich eine Liste der Händler, und wenn ich einen Händler in der Listview wählen, dann sollte ich sehen, Details über den Händler, einschließlich des Namens des Händlers und die Liste der Autos.

Meine Frage ist, wie kann ich die Liste der Autos an eine Listenansicht binden, da es eine Eigenschaft des Dealer-Objekts ist? Konkret, was soll ich in meinem Sichtmodell haben? Ich brauche die Liste der zu aktualisierenden Autos, wenn ich etwas zur Sammlung hinzufüge, also habe ich das Gefühl, dass ich eine ObservableCollection brauche. Dies scheint jedoch dazu zu führen, dass für jeden Händler zwei Sammlungen (eine Liste und eine ObservableCollection) vorhanden sind, und diese Doppelung von Daten scheint sowohl hinsichtlich der Codierung als auch der Leistung ineffizient zu sein. Irgendwelche Ideen?

+0

Sie haben absolut Recht. Realisiert habe ich die Frage nicht beantwortet, gelöschte Antwort. –

Antwort

2

Wir haben die Modelllisten innerhalb einer ObservableCollection zusammengefasst. Diese ObservableCollection ist normalerweise auch ein ViewModel für das Child-Objekt, sodass wir ihre Ansicht steuern und das ViewModel bei Bedarf an eine andere Ansicht übergeben können. Sie werden zwei Listen haben, die jedoch die gleichen Objektreferenzen enthalten. Es mag wie eine Doppelarbeit erscheinen, aber mit einer anständigen Verwendung der Vererbung können Sie immer noch einen DRY-Ansatz beibehalten. Denken Sie daran, dass die Idee von MVVM darin besteht, eine Abstraktion zwischen Ihrer Ansicht und dem Modell zu erstellen. Es könnte so aussehen, als würden Sie sich die Mühe sparen, indem Sie die Child-Objekte nicht umbrechen, aber wir haben fast immer die Notwendigkeit, diese Child zu transformieren Objekte später.

2

Ok, erstens gibt es einen Grund, warum Sie einen ListView über eine ListBox verwenden? Wenn Sie nicht sicher sind, welches Sie verwenden sollen, würde ich eine ListBox verwenden. Lassen Sie eine ListBox an Ihre Händlerliste auf Ihrem View-Modell binden, die eine ObservableCollection wäre, wenn Sie Händler hinzufügen/entfernen möchten. Dann binden Sie den SelectedValue dieser ListBox an eine Dealer-Eigenschaft in Ihrem Ansichtsmodell, vielleicht SelectedDealer genannt.

Dann haben Sie eine zweite ListBox, die die Liste der Autos für den ausgewählten Händler zeigt. Binden Sie die DataContext-Eigenschaft der Auto-ListBox an den SelectedDealer und binden Sie die ItemsSource an Cars. Dann wird Ihre Auto-ListBox an die Sammlung von Autos gebunden, die auf dem ausgewählten Händler sitzen.

Wenn Sie Autos hinzufügen/entfernen und die Benutzeroberfläche aktualisieren möchten, sollten Sie eine ObservableCollection verwenden. Sie möchten nicht, dass Ihre Geschäftsobjekte ObservableCollections zurückgeben, daher sollte diese Konvertierung für Ihre Ansichtsmodelle durchgeführt werden. Sie könnten vielleicht eine ObservableCollection-Eigenschaft in Ihrem Ansichtsmodell namens SelectedCars haben und Ihr Auto-Listenfeld an dieses binden. In dem Setter für SelectedDealer, Sie so etwas wie tun könnten:

public ObservableCollection<Car> SelectedCars { get; set; } 

private Dealer selectedDealer; 
public Dealer SelectedDealer 
{ 
    get 
    { 
    return this.selectedDealer; 
    } 

    set 
    { 
    if (this.selectedDealer != value) 
    { 
     this.selectedDealer = value; 
     this.SelectedCars = new ObservableCollection(this.SelectedDealer.Cars); 
     OnPropertyChanged(() => this.SelectedDealer); 
    } 
    } 
} 

In diesem Fall würden Sie nicht die Datacontext Ihres Auto listbox zum SelectedDealer gesetzt, würde der Datacontext nicht eingestellt werden, und das View-Modell würde implizit verwendet werden. Dann binden Sie einfach die ItemsSource der Auto-Listbox an die SelectedCars-Eigenschaft.

0

Persönlich würde ich die 'Autos' Sammlung in ein anderes Objekt zum Beispiel ein 'Stock' Objekt abstrahieren. Ich würde niemals eine Liste oder beobachtbare Sammlung verfügbar machen, da dies die Kapselung unterbricht. Ich würde ein ienumerable mit adstock- und removestock-Methoden auf dem Stock-Objekt verfügbar machen, um das relevante Verhalten einzukapseln. Im View-Modell würde dieses Verhalten darin bestehen, die entsprechende Methode im Model aufzurufen und die relevanten INotifyPropertyChanged-Ereignisse auszulösen. Das Stock-Objekt würde sein eigenes View-Modell haben, das so mit dem IEnumerable auf dem Stock ViewModel verbunden wäre.

Verwandte Themen