Несколько ViewModels, связанных с одним представлением - PullRequest
18 голосов
/ 15 июля 2010

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

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

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

Спасибо!

Ответы [ 3 ]

38 голосов
/ 15 июля 2010

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

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

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

11 голосов
/ 16 июля 2010

Я думаю, это не рекомендуемый дизайн, это далеко не нарушение правил.По крайней мере, в моих проектах вы будете неоднократно видеть этот шаблон.

Этот шаблон особенно полезен в сочетании с 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.и вы автоматически получаете приведенный выше шаблон данных для каждого игрока:

<ListBox ItemsSource="{Binding Players}"/>
3 голосов
/ 17 июля 2010

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

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

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

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

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

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...