Страницы

Поиск по вопросам

пятница, 29 ноября 2019 г.

Точка входа в MVVM: App.xaml.cs или представление?

#c_sharp #wpf #mvvm #mvvm_light


Начал изучать MVVM и столкнулся, как наверное и многие другие, с определенным недопониманием.
В многочисленных примерах реализации MVVM, доступных в сети, авторы разными способами
подходят к точке входа в приложение (могу ошибаться в определении). Некоторые меняют
аттрибут StartupUri, другие просто его полностью удаляют и в перегруженном методе OnStartup
файла App.xaml.cs вручную создают экземпляр окна и устанавливают ему свойство DataContext.
Нашел в сети несколько примеров по MVVM и mvvm-light (пример 1, пример 1, пример 3,
пример 4 и пример 5) и в них автор вообще не изменяет App.xaml или App.xaml.cs и только
в одном изменяет code-behind (так и не понял как это называется по-русски) представлений.

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


Ответы

Ответ 1



Я предпочитаю не использовать StartupUri, а переопределять OnStartup, и создавать главное окно там ([1], [2], [3]). Причина в том, что указание StartupUri не позволяет задать DataContext снаружи окна. А хардкодирование DataContext'а внутри XAML неправильно, так как: Согласно паттерну MVVM, View не должно руководить VM, и знать о нём должно как можно меньше. То есть код, обслуживающий UI, не должен создавать себе VM сам. Чаще всего VM должна получить ещё какие-то аргументы в конструкторе (например, модельные объекты), а это не получится сделать, если VM создаётся в XAML'е (откуда XAML может знать о модели?). Иногда перед открытием главного окна нужна дополнительная логика, требующая показа своего маленького окна (например, предложение обновить программу). Или нужно выяснить, какое именно из окон нужно показывать в начале. Код, выясняющий это и при некоторых условиях показывающий дополнительное окно, проще разместить в OnStartup. Главная VM может понадобиться вам для ещё чего-нибудь. Поэтому если её создаёт класс App, он может сохранить ссылку на неё у себя, чтобы другие (например, побочное окно) могли быть привязаны к тому же экземпляру VM. Иначе вам придётся лезть за главной VM в экземпляр главного окна. В любом случае, MVVM не догма, делайте так, как вам удобнее.

Комментариев нет:

Отправить комментарий