Wiele modeli widoków powiązanych z jednym widokiem

Mam widok, który wyświetla DataGrid, który jest związany z ObservableCollection w ViewModel. Na potrzeby dyskusji Załóżmy, że mamy Team widok zawierający zespół DataGrid, w którym każdy wiersz reprezentuje Player.

Moje pytanie dotyczy tego, jakiego typu danych powinienem użyć do reprezentowania graczy w mojej kolekcji Team. Czy dobrym pomysłem jest, aby przedmioty w kolekcji były same Viewmodelami? W tym przypadku Mój widok Team będzie powiązany z pojedynczym Team ViewModel oraz dowolna liczba Player ViewModels (w kolekcji Team).

Czy posiadanie wielu Viewmodeli powiązanych z pojedynczym widokiem narusza jakiekolwiek wytyczne projektowe dla MVVM i czy istnieje preferowany sposób implementacji tego scenariusza?

Dzięki!
 22
Author: STiLeTT, 2010-07-15

4 answers

Nie, to jest w porządku; każdy obiekt powinien być ViewModel sam w sobie. To sprawia, że czystszy kod, ładniejsze interakcje, i pamiętaj, jeśli to działa dobrze, to jest poprawne (nawet jeśli narusza Wytyczne).

Zrobiłbym to dokładnie tak, jak pan przepisuje. Chciałbym powiązać moją siatkę z Team, która miałaby ObservableCollection<Player>, Gdzie Player jest inną klasą typu ViewModel. Każdy element wiersza otrzyma {[2] } jako swój DataContext, więc nadal będziesz wiązał właściwości ViewModel, jak można się spodziewać: i Player może nadal mieć public właściwości dla ICommand s (prawdopodobnie polecenia RelayCommands) do manipulacji!

Mam nadzieję, że to pomoże!

 41
Author: Kieren Johnstone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-15 19:52:44

Daleki od naruszania wytycznych, myślę, że jest to zalecany projekt. Przynajmniej w moich projektach zobaczysz ten wzór wielokrotnie.

Ten wzór jest szczególnie przydatny w połączeniu z Datatematplates. Na przykład można zdefiniować płytę danych w aplikacji.Zasoby dla PlayerViewModel jak TAK:

<DataTemplate DataType="viewModels:PlayerViewModel">
    <StackPanel Orientation="Vertical">
        <Image Source="/Images/Player.png"/>
        <TextBlock Text="{Binding Name}"/>
    </StackPanel>
</DataTemplate>

A następnie, jeśli chcesz wyświetlić listę graczy, po prostu powiązaj ListBox etc ze swoim TeamViewModel.Gracze ObservableCollection I ty automatycznie wyświetla się powyższa tablica danych dla każdego gracza:

<ListBox ItemsSource="{Binding Players}"/>
 12
Author: Grokys,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-15 21:55:50

Zgadzam się z obydwoma innymi odpowiedziami (tymi Kierena i Groky ' ego), ale czuję, że nie wspominają o bardzo ważnej kwestii w tej decyzji.

Powinieneś utworzyć model widoku tylko wtedy, gdy jest coś konkretnego w tym, co robisz. Jeśli wszystko, co robisz, to powiązanie z danymi i wywołanie poleceń, które naturalnie należą do twojego modelu, nie ma powodu, aby tworzyć model widoku.

Na przykład, załóżmy:

  1. twój obiekt gracza ma właściwość Name, właściwość Rank, metoda Promote() i metoda Delete ().
  2. twój widok jest prosty, który pozwala edytować nazwę i rangę dowolnego gracza, a także ma przyciski do promowania i usuwania graczy.

W tym przypadku dodawanie modelu widoku między widokiem a modelem jest bezcelowe. Taki widok może wiązać się bezpośrednio z modelem:

  • Bind TextBox.Tekst do właściwości Name
  • Bind Slider.Wartość do Właściwości Rank
  • powiązać przycisk Promuj z Metoda Promote ()
  • Połącz przycisk Delete z metodą Delete ()

Zauważ, że zamiast wiązania przycisku Delete z metodą Delete() możesz ustawić jego polecenie na ApplicationCommands.Usuń i użyj funkcji CommandBinding, aby wywołać metodę Delete ().

Chodzi mi o to, że w większości przypadków, jeśli twoje modele są dobrze zaprojektowane, nie będzie potrzeby wstawiania obiektu modelu widoku. Model widoku jest naprawdę potrzebny tylko wtedy, gdy trzeba śledzić stan specyficzny dla widoku (np." bieżący Odtwarzacz"), konwersje są zbyt złożone, aby mogły być obsługiwane przez proste Wiązanie lub potrzebne są polecenia, które wpływają na kilka różnych obiektów modelu i / lub wyświetlają właściwości modelu w tym samym czasie.

Z mojego doświadczenia wynika, że jeśli model jest poprawnie zaprojektowany tylko około 50% wszystkich widoków faktycznie potrzebuje modelu widoku, a w przypadku pozycji na liście jest to raczej 20%.

Przykładem czasu, kiedy można użyć modelu widoku dla elementu na liście jest czas, gdy trzeba zachować oddzielna flaga "wybrana", która jest częścią widoku, ale nie Modelu, a podstawowa funkcjonalność w ListBox to za mało.

 4
Author: Ray Burns,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-17 04:58:33

By CLEAN COD SOLID principles, it is nice to associate one view model to one view. Rozdzielenie problemów powinno być rozdzielone dla każdego widoku i o wiele łatwiej jest utrzymać bazę kodu w przyszłości. Możesz to zrobić, ale nie jest to zalecane.

 1
Author: Martin Gelevski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-13 13:55:18