Несколько ViewModels, связанных с одним представлением

У меня есть представление, которое отображает DataGrid, привязанный к ObservableCollection в ViewModel. Для обсуждения предположим, что у нас есть Team View, содержащий команду DataGrid, в которой каждая строка представляет Player.

Мой вопрос о том, какой тип данных я должен использовать для представления игроков в моей коллекции Team. Является ли хорошей идеей для элементов в коллекции самими ViewModels? В этом случае мой Team View будет связан с одним Model > t22 > , а также с любым количеством Player ViewModels (в коллекции Team).

Имеет ли несколько ViewModels, связанных с одним просмотром, нарушать любые руководящие принципы проектирования для MVVM и есть ли предпочтительный способ реализации этого сценария?

Спасибо!

Ответы

Ответ 1

Нет, это нормально; каждый объект должен быть ViewModel самостоятельно. Он делает для более чистого кода, более приятных взаимодействий и запоминает, если он работает хорошо, тогда он исправляется (даже если он нарушает правила).

Я бы сделал это именно так, как вы предписываете. Я привязал бы свою сетку к Team, у которой был бы ObservableCollection<Player>, где Player - другой класс типа ViewModel. Каждый элемент строки получит Player как его DataContext, и поэтому вы по-прежнему привязываетесь к свойствам ViewModel, как и следовало ожидать: и Player может по-прежнему иметь свойства public для ICommand (вероятно, RelayCommands) для манипуляция!

Надеюсь, что это поможет!

Ответ 2

В отличие от рекомендаций, я считаю, что это рекомендуемый дизайн. По крайней мере, в моих проектах вы увидите этот шаблон повторно.

Этот шаблон особенно полезен в сочетании с DataTemplates. Например, вы можете определить 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}"/>

Ответ 3

Я согласен с обоими другими ответами (Киреном и Гроки), но считаю, что они не упоминают очень важное соображение в этом решении.

Вы должны создать только модель представления, если есть что-то конкретное в отношении того, что вы делаете. Если все, что вы делаете, является привязкой к данным и вызовам команд, которые, естественно, принадлежат вашей модели, нет причин создавать модель представления.

Например, предположим:

  • Объект Player имеет свойство Name, свойство Rank, метод Promote() и метод Delete().
  • Ваше мнение является простым, позволяющим редактировать имя и рейтинг любого игрока, а также кнопки для продвижения и удаления игроков.

В этом случае добавление модели представления между вашим представлением и вашей моделью бессмысленно. Такое представление может напрямую связываться с моделью:

  • Привязать TextBox.Text к свойству Name
  • Bind Slider.Value к свойству Rank.
  • Привяжите кнопку Promote к методу Promote()
  • Привяжите кнопку "Удалить" к методу "Удалить" ()

Обратите внимание, что вместо привязки кнопки Delete к методу Delete() вам может потребоваться установить команду Command в ApplicationCommands.Delete и использовать CommandBinding для вызова метода Delete().

Моя точка зрения заключается в том, что в большинстве случаев, если ваши модели хорошо разработаны, не потребуется вставлять объект модели представления. Модель просмотра действительно нужна только тогда, когда нужно отслеживать состояние, специфичное для просмотра (например, "текущий проигрыватель" ), конверсии слишком сложны, чтобы обрабатываться простой привязкой, или вам нужны команды, которые влияют на несколько разных объектов модели и/или вид свойства модели одновременно.

По моему опыту, если модель правильно спроектирована, то примерно 50% всех представлений действительно нуждаются в модели представления, а в случае элементов в списке это больше похоже на 20%.

Пример времени, когда вы можете использовать модель представления для элемента в списке, - это когда вам нужно сохранить отдельный "выбранный" флаг, который является частью вашего представления, но не вашей модели, и основные функции в ListBox недостаточно.