2013-08-12 9 views
6

Considera un'app WPF che viene scritta utilizzando MVVM. L'app deve visualizzare un elenco di Dipendenti (Nome, Cognome, Titolo) ed è possibile selezionare più elementi da eliminare.Visualizza solo proprietà (ad esempio: IsSelected) e il modello in MVVM

Il modello in questo caso sarebbe "dipendenti" e sarebbe implementare INotifyPropertyChanged.

La vista sarebbe "EmployeeListView" che implementerebbe XAML per visualizzare una raccolta di Impiegati.

Il ViewModel sarebbe "EmployeeListViewModel" che esporre un ObservableCollection, che possono essere collegati al EmployeeListView.

La mia domanda è: dove dovrebbe vivere la proprietà "IsSelected"?

  1. Nel modello? (Non mi piace questa idea, poiché il modello ora espone una proprietà che è richiesta solo da una vista e non ha nulla a che fare con l'oggetto dominio effettivo, inoltre, questa proprietà sarebbe inutile, se implementassi la vista in modo diverso e non lo facesse consentire la cancellazione di più dipendenti contemporaneamente).
  2. Nel "EmployeeListViewModel" come una raccolta di dizionari separata, che dovrebbe tenere traccia se un dipendente è selezionato o meno? (O anche solo un HashSet che contiene tutti i dipendenti selezionati). Non mi piace così tanto come l'associazione nella vista non è più diretta.
  3. Implementare un EmployeeViewModel separato, che avvolge l'oggetto Impiegato ed espone la proprietà IsSelected. EmployeeListViewModel espone quindi la sua collezione come ObservableCollection. Mi piace questa soluzione al meglio, ma ho sempre pensato che ci fosse un ViewModel per View e in questo caso ho 2 view-models per la mia vista. È una deviazione dal pattern MVVM o è questo il modo tipico di implementare MVVM? (riferimenti?)

risposta

6

Creare un SelectableItem generico riutilizzabile che avvolge ogni elemento nella employeeList:

semplice esempio:

public class SelectableItem<T>: INotifyPropertyChanged 
{ 
    public bool IsSelected {get;set;} //PropertyChanged(), etc 

    public T Value {get;set;} 
} 

poi nel ViewModel:

public ObservableCollection<SelectableItem<Employee>> Employees {get;set;} 

e nella view:

<DataTemplate> 
    <CheckBox IsChecked="{Binding IsSelected}" Content="{Value.FullName}"/> 
</DataTemplate> 

Quindi è possibile recuperare tutti i dipendenti selezionati semplicemente:

var selectedemployees = Employees.Where(x => x.IsSelected).Select(x => x.Value); 
+1

+1, trovo sempre che questa sia la soluzione più semplice. –

+0

Mi piace questa soluzione. Ma anche se chiedo di implementare IsSelected, la mia domanda riguarda anche se il suo kosher è MVVM per avere più ViewModels usati da una View. Inoltre, isnt SelectableItem a ViewModel e nel qual caso questo è simile alla mia soluzione # 3, ma appena implementato in un modo più generico?(Cosa succede se ho più elementi specifici dell'interfaccia utente da tracciare: IsChecked, IsSelected, etc, e non tutte le interfacce utente necessitano di queste diverse proprietà da tracciare) –

+4

È totalmente accettabile avere più VM in on View. In effetti, puoi pensare che ogni controllo su una vista sia una vista. L'esempio migliore è quando si dispone di un DataGrid in cui ogni riga avrà la propria VM. – sacha

Problemi correlati