Как правильно передавать данные из 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 запросы на изменение этих данных. Обычно я смотрю доки по конкретным контролам и там сразу есть примеры типичных привязок для этого контрола.