У меня есть Представление, которое отображает a DataGrid
который связывается с ObservableCollection
в ViewModel. Ради обсуждения скажем, у нас есть a Team
Представление, содержащее Команду DataGrid
, в котором каждая строка представляет a Player
.
Мой вопрос, о каком типе данных я должен использовать для представления плееров в моем Team
набор. Действительно ли это - хорошая идея для объектов в наборе, чтобы быть ViewModels самих? В этом случае, мой Team
Представление было бы связано с синглом Team
ViewModel, а также любое количество Player
ViewModels (в наборе Команды).
Наличие нескольких ViewModels, связанных с единственным Представлением, нарушают какое-либо руководство по проектированию для MVVM, и есть ли предпочтительный способ реализовать этот сценарий?
Спасибо!
Нет, ничего страшного; каждый объект должен быть отдельной моделью ViewModel. Это делает код более чистым, взаимодействие более приятным, и помните, что если он работает хорошо, то он правильный (даже если он нарушает правила).
Я бы сделал именно так, как вы прописываете.Я бы привязал свою сетку к группе Team
, которая имела бы ObservableCollection
, где Player
- это еще один класс типа ViewModel. Каждый элемент строки получит Player
в качестве своего DataContext
, поэтому вы по-прежнему привязываетесь к свойствам ViewModel, как и следовало ожидать:и Player
все еще может иметь общедоступные
свойства для ICommand
s (вероятно, RelayCommands) для манипуляций!
Надеюсь, это поможет!
Я считаю, что это рекомендуемый дизайн, а не нарушение правил. По крайней мере, в моих проектах вы встретите этот узор неоднократно.
Этот шаблон особенно полезен в сочетании с шаблонами данных. Например, вы можете определить DataTemplate в своем Application.Resources для вашей PlayerViewModel следующим образом:
<DataTemplate DataType="viewModels:PlayerViewModel">
<StackPanel Orientation="Vertical">
<Image Source="/Images/Player.png"/>
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
А затем, если вы хотите отобразить список игроков, вы просто привяжете ListBox и т. Д. К своей TeamViewModel.Players ObservableCollection, и вы автоматически получите указанное выше DataTemplate отображается для каждого игрока:
<ListBox ItemsSource="{Binding Players}"/>
Я согласен с обоими другими ответами (ответами Кирена и Гроки), но чувствую, что они не упоминают очень важное соображение в этом решении.
Вам следует создавать модель представления только в том случае, если есть что-то зависящее от представления о том, что вы делаете. Если все, что вы делаете, это привязка к данным и вызов команд, которые естественно принадлежат вашей модели, нет причин создавать модель представления.
Например, предположим:
В этом случае добавление модели представления между вашим видом и вашей моделью бессмысленно. Такое представление может быть привязано непосредственно к модели:
Обратите внимание, что вместо привязки кнопки «Удалить» к методу Delete () вы можете хотите установить для своей команды значение ApplicationCommands.Delete и использовать CommandBinding для вызова метода Delete ().
Я хочу сказать, что в большинстве случаев, если ваши модели хорошо спроектированы, нет необходимости вставлять объект модели представления. Модель представления действительно необходима только тогда, когда необходимо отслеживать состояние, зависящее от представления (например, «текущий игрок»), преобразования слишком сложны, чтобы их можно было обрабатывать с помощью простой привязки, или вам нужны команды, которые влияют на несколько различных объектов модели и / или представления. свойства модели одновременно.
По моему опыту, если модель правильно спроектирована, только около 50% всех представлений действительно нуждаются в модели представления, а в случае элементов в списке это больше похоже на 20%.
Примером случая, когда вы можете использовать модель представления для элемента в списке, является то, когда вам нужно сохранить отдельный флаг «выбранный», который является частью вашего представления, но не вашей модели, и базовые функции в ListBox недостаточно.