Как правильно передавать данные из Model во View и обратно в архитектуре MVVM и что для этого делать во ViewModel?
Хотел бы задать вопросы ответы на которые я не могу найти(скорее всего плохо ищу):
- как в модель заполнять данные из sql/файла(перед инициализацией окна создавать экземпляр Model и туда засовывать данные или как-то по другому?)
- Как изменять данные Model и записывать их?(Точнее где, могу ли я в ViewModel изменять данные и вызывать методы обновления данных в sql/файле?)
- Как мне брать данные из view и передавать в ViewModel или в Model?(брать в ViewModel через обращение к элементам и передавать методом в Model или есть другие более правильные способы?)
Ответы (1 шт):
Я относительно недавно снова начал заниматься 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
запросы на изменение этих данных. Обычно я смотрю доки по конкретным контролам и там сразу есть примеры типичных привязок для этого контрола.