Как правильно передавать данные из Model во View и обратно в архитектуре MVVM и что для этого делать во ViewModel?

Хотел бы задать вопросы ответы на которые я не могу найти(скорее всего плохо ищу):

  1. как в модель заполнять данные из sql/файла(перед инициализацией окна создавать экземпляр Model и туда засовывать данные или как-то по другому?)
  2. Как изменять данные Model и записывать их?(Точнее где, могу ли я в ViewModel изменять данные и вызывать методы обновления данных в sql/файле?)
  3. Как мне брать данные из view и передавать в ViewModel или в Model?(брать в ViewModel через обращение к элементам и передавать методом в Model или есть другие более правильные способы?)

Ответы (1 шт):

Автор решения: CrazyElf

Я относительно недавно снова начал заниматься WPF, поэтому не факт что всё делаю правильно, но постараюсь объяснить основные концепции.

  • Отображение данных происходит во View, а данные для этого отображения подготавливаются во ViewModel.
  • ViewModel общается с Model и прочей бизнес-логикой совершенно обычным программным образом - например, через паттерн "репозиторий", и может запрашивать данные у модели или просить их сохранить. Просто вызывает для этого те или иные методы модели и получает результат.
  • Первоначальное состояние модели можно задать сразу когда ViewModel инстанциируется. Просто в конструкторе запрашиваете данные из модели.
  • Наиболее хороший способ отображения данных во View из ViewModel - через Binding-и. Просто кладёте данные в некое свойство и дёргаете OnPropertyChanged с именем этого свойства - View таким образом узнаёт, что данные изменились, смотрит, на какие элементы View сделаны Binding-и этого свойства и подтягивает туда новые данные.
  • И в обратную сторону тоже самое: вы меняете какие-то элементы во View, у них сделан Binding обратно к источнику (обычно просто делается "двусторонний binding" с помощью параметра Mode=TwoWay) и поэтому дёргается во ViewModel соответствующее свойство, ну а там вы сами реализуете логику, что в этом случае делать в сеттере этого свойства, как меняется состояние модели, при этом опять меняются какие-то ещё свойства и они обратно во View отображаются через их binding-и.

Таким образом, в WPF всё строится на:

  • Привязках / bindings, причём привязки очень гибкие, можно привязать:
    • Источник данных (сразу целую таблицу к её вью)
    • Поля объектов (при отображении в контроле указать, какое поле объекта брать для вывода)
    • Поле объекта для проверки в триггере и установки стиля вывода этого объекта
    • И многое другое, например, завязать видимость каких-то объектов на значение какого-то свойства во ViewModel и т.д.
  • OnPropertyChange (либо коллекциях, которые сами оповещают об изменениях в себе, самому тут ничего дёргать не нужно - например, ObservableCollection, или DataTable)
  • Командах / сommands - это примерно как события, но события в WPF отрабатывают в code behind View, а команды направляются в ViewModel и дёргают некие события там

Да, какую-то логику можно и в code behind view делать, но это когда вы не можете сделать через связь с ViewModel и не очень рекомендуется.

В общем, с одной стороны MVVM это зачастую совершенно обычный программный код, читающий данные из бэкэнда стандартным образом. А с другой стороны, вы не должны в нём напрямую обращаться к элементам интерфейса, а стараться отдавать и получать данные с помощью привязок и команд (в крайнем случае - событий).

Тут главное настроиться на эту парадигму, которая поначалу кажется довольно непривычной.

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

→ Ссылка