2013-08-12 10 views
6

Rozważ aplikację WPF, która jest zapisywana przy użyciu MVVM. Aplikacja musi wyświetlić listę pracowników (FirstName, LastName, Title) i możesz wybrać wiele do usunięcia.Wyświetl tylko właściwości (np. IsSelected) i model w MVVM

model w tym przypadku byłoby „Pracownik” i byłoby wdrożyć INotifyPropertyChanged.

Widok byłby "EmployeeListView", który zaimplementował XAML, aby wyświetlić kolekcję pracowników.

ViewModel byłoby "EmployeeListViewModel", który naraziłby się ObservableCollection, które mogą być związane z EmployeeListView.

Moje pytanie brzmi: Gdzie powinien znajdować się obiekt "IsSelected"?

  1. W modelu? (Nie podoba mi się ten pomysł, ponieważ model teraz ujawnia właściwość, która jest wymagana tylko przez widok i nie ma nic wspólnego z rzeczywistym obiektem domeny, także ta właściwość byłaby bezużyteczna, jeśli zaimplementowałem widok inaczej i nie zrobiłbym pozwalają na jednoczesne usunięcie wielu pracowników).
  2. W "EmployeeListViewModel" jako osobnej kolekcji słowników, która śledziłaby wybór pracownika, czy nie? (Lub nawet tylko HashSet zawierający wszystkich wybranych pracowników). Nie podoba mi się to tak bardzo, ponieważ wiązanie w widoku nie jest już proste.
  3. Wykonaj osobny EmployeeViewModel, który otacza obiekt pracownika i ujawnia właściwość IsSelected. Następnie EmployeeListViewModel ujawni swoją kolekcję jako ObservableCollection. Najbardziej lubię to rozwiązanie, ale zawsze uważałem, że istnieje jeden ViewModel na widok i w tym przypadku mam 2 modele widoku dla mojego widoku. Czy to odchylenie od wzorca MVVM, czy jest to typowy sposób wdrożenia MVVM? (odniesienia?)

Odpowiedz

6

Tworzenie wielokrotnego użytku Generic SelectableItem która otacza każdą pozycję w EmployeeList:

prosty przykład:

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

    public T Value {get;set;} 
} 

następnie w ViewModel:

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

iw widoku:

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

Następnie można pobrać wszystkie wybrane przez pracowników tylko:

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

+1, zawsze znajdę to być najprostszym rozwiązaniem. –

+0

Podoba mi się to rozwiązanie. Ale chociaż pytam o implementację IsSelected, moje pytanie dotyczy także tego, czy jego koszerna jest MVVM, aby wiele ViewModeli było używanych przez jeden widok. Ponadto, nie jest SelectableItem a ViewModel iw takim przypadku jest to podobne do mojego rozwiązania # 3, ale po prostu zaimplementowane w bardziej ogólny sposób?(Co się stanie, gdy będę miał więcej elementów do śledzenia UI - IsChecked, IsSelected, itp., A nie wszystkie UI będą wymagały śledzenia różnych właściwości) –

+4

Całkowicie dopuszczalne jest posiadanie wielu maszyn wirtualnych w widoku. W rzeczywistości możesz myśleć, że każda kontrolka w widoku jest samym widokiem. Najlepszym przykładem jest posiadanie DataGrid, gdzie każdy wiersz będzie miał swoją własną maszynę wirtualną. – sacha

Powiązane problemy