LINUX.ORG.RU

Как должен быть устроен сервис управления окон в строгой реализации MVVM???

 


1

2

Пишу на С# WPF. Паттерн MVVM. Нельзя ViewModel дать ссылку на View => для открытия окон нужен сервис который будет ими управлять. В примерах из интернета либо непонятно, либо они дают ссылку на View и напрямую обращаются к окну Window.xaml.

Как этот сервис должен быть устроен?

Как вариант рассматривался интерфейс с методами Open(), Close(), но опять же туда передают окно.

Где-то в интернете вставляли туда MyViewModel, но как через привязанный ViewModel открывать окно - непонятно.

Помогите!!!

Пошагово объясните как должен работать этот сервис.

Спасибо.

Ну я вчера жевал это добро, правда на авалонии и там куда сложнее просто окно передать, чем в случае WPF (не сложнее, можно его в конструктор засунуть, но вот только превьюшка от этого сломается, потому как превьюшка авалонии не умеет в конструкторы с параметрами). На самом деле говнодизайн когда упоротые всё строго по MVVM или ещё какому-то паттерну делают. Это как всё на лямбдах писать или вообще всё без лямбд. Никто в здравом уме так не делает почему-то если ЯП содержит лямбды. Но совсем упоротые авторы авалонии (а упороты они потому что пытаются ежа с носорогом скрестить - а именно десктоп модель с окнами и мобильную модель с активити которые ни разу не окна) там костылики подложили, вроде такого:

var mainWindow = Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop ? desktop.MainWindow : null;
чтоб можно было добраться до окна из любого места (правда тут всё сильно от версии авалонии зависит и костылик менялся по времени). Так реально костыли часто используют, я бы не стал заморачиваться особо, если окном прямо плотно не нужно управлять. Одно только закрытие и открытие окон как по мне можно и через костыли делать. А так что-то типа такого пилить https://learn.microsoft.com/en-us/archive/msdn-magazine/2013/march/mvvm-messe.... ХЗ короче, стоит спросить lovesan, может он правильнее подскажет.

peregrine ★★★★★
()
Последнее исправление: peregrine (всего исправлений: 1)
Ответ на: комментарий от peregrine

Да при том самое весёлое в том, что если это в конструкторе инициализировать, то ничего не получится, оно и понятно, потому как все эти Application.Current перестанут быть null только после инициализации, фактически после отрисовки окна. Т.е. если повесить такой код на кнопку, то нормально - добраться до окна получится. А если повесить его в конструктор, то там будет null по очевидным причинам. В итоге с одной стороны MVVM решает проблемы больших проектов, делая код более структурированным. С другой стороны оно очевидно усложняет код в случае простых проектов. Т.е. я отлично понимаю зачем MVVM в вебе, когда страничек много, компонентов на страничке тоже много и не понимаю когда его начинают пихать в программки с 10 контролами и 2 окошками. Т.е. ничего кроме жирного монстра, вроде условного фотошопа для MVVM на десктопе мне в голову не приходит. Условному файловому менеджеру или DB Browser for SQLite MVVM ну такое как по мне. Неужели большая часть десктопного софта, которая разрабатывается сейчас это монстры вроде 3D/2D редакторов (сколько их там в мире серьёзных штук 10 наверное)? И весь сыр бор ради того чтоб условным 5000 разработчиков из условного 1 000 0000 в мире стало легче?

anonymous
()

Нельзя ViewModel дать ссылку на View =>

Кто ж тебе запретит? ;)

В примерах из интернета либо непонятно, либо они дают ссылку на View и напрямую обращаются к окну Window.xaml.

Ну так в примерах бойлерплейт весь ликвидирован для ясности и либо «модель фест», либо вьюха. Либо вьюхи в вьюмоделях, либо вьюмодели во вьюхах. Как левая нога автора видит. Совой об пень — пнем об сову, а где создавать экземпляры в общем и целом монопенисуально. Можно их в коллекцию засунуть, или на ходу создавать из «более модного» свича, как авторы фреймворков и делают. Главное чтоб вьюха в каждый момент имела контекст, который никто не мешает подсовывать ручками.

В авалониях, да и в WPFах, обычно локатор какой-нибудь делает это за тебя. Пуристы возникают что и «локатор нельзя», т.к. у старого кукаретика Мартина вычитали что это «антипаттерн» (при этом открываешь примерно любой фреймворк — а там ехал локатор через локатор). «А если нельзя, но очень хочется» то и кодбехайнд во все поля — типа в обработчике когда вьюха аттачится к вьюмодели — берут и делают.

Но для начала ты бы ответил для себя «Чтобы что?» :)

slackwarrior ★★★★★
()

Как этот сервис должен быть устроен?

Я бы посоветовал посмотреть в сторону локаторов в реальный проект, как там сделано, типа такого https://github.com/IngvarX/Camelot. Погонять его в дебагере, что происходит при переходе от моделей через сервисы к вьюхам, если хочется максимально через ж... жэсточайшые абстрактные приседания ;)

slackwarrior ★★★★★
()
Последнее исправление: slackwarrior (всего исправлений: 1)

Пошагово объясните как должен работать этот сервис.

*Затягивается донским табаком*

Не знаю, как должен, а обычно они работают как-то так: сервис получает какой-то ключ, по которому будет искать нужную вьюмодель. Это может быть енум, токен типа, Type class, интерфейс — кому как удобнее. Мазохисты создают сервис на каждый чих. И потом сами не помнят где что. У этого конкретного сервиса под капотом обычно есть какой-то «фабричный» (ТМ) способ поиска («ни в коем случае не локации!» :)) цели для захардкоженного (раннего)... или позднего... или «на ходу» связывания. Т.е. свич из Typeов вьюх в вызовы оператора new для вьюмоделей, словарь экземпляров, словарь террористов для взрывов на фабрике вьюмоделей.

В «самый моменд О» (обнаружения, ни в коем-случае не локации!) нужного способа, этот сервис дергает... другой сервис, который знает «как», а тот возвращает экземпляр нужной вьюмодели в качестве контекста для вьюхи.

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

При этом надо учитывать, что MVVM как «паттерн разделения» справляется «болиемение» именно с разделением — как потом общаться разделенным экземплярам в абстрактных примерах объясняют редко (для этого решают собственноручно созданные проблемы добавлением «шины сообщений» и прочие «подписки» на спрятанный под семь слоев абстракций визитор с локатором).

Вью-модели таким образом могут создаваться на лету — для юзера это неотличимо от «открытия окна». И только модели, которые живут дольше всех, знают, какая на самом деле шляпа под капотом :)

slackwarrior ★★★★★
()
Последнее исправление: slackwarrior (всего исправлений: 1)
Ответ на: комментарий от slackwarrior

А не знаешь случайно какого-то хорошего проекта на авалонии? Который достаточно прост, но в то же время написан красиво более-менее по правилам? Посмотреть как люди делают некоторые вещи очень хочется, т.к. родная документация не то чтоб хорошая была. Что-то из классики, где не одно окно в котором вьюхи переключают, а чтоб несколько окон было реализовано. А то страдаю я с тем как правильно такую тривиальную вещь как открытие второго окна без дикого уродства сделать, сказывается что WPF не использовал никогда серьёзно, потому и reactiveui для меня немного диковатый зверёныш, смотрю проект из демки https://docs.avaloniaui.net/docs/tutorials/music-store-app/opening-a-dialog напрягает если честно немного. Все вот эти вот Interaction<TInput, TOutput>, как бы документация по ним тут хорошая https://www.reactiveui.net/docs/handbook/interactions/ но возможностей глаза разбегаются, может можно как-то проще делать в тривиальных случаях, например, если показать условный аналог MessageBox в котором не надо передавать TInput, понятно что можно Unit вместо него передать, но всё же глаза разбегаются. Подозреваю что обычно авалонию после WPF берут, а мне на шарпе повсеместно винформы встречались и устраивали меня по большей части, а потом на python переполз.

peregrine ★★★★★
()
Ответ на: комментарий от peregrine

Если тоскуешь по винформсам и посконной простоте, то... лучший твой друг — класс Window. Я серьезно. Полная свобода и главное правило — «не упарываться». Просто создаешь экземпляры окон явочным порядком и вызываешь в обработчиках mywindow.Show(); Единственно, твоим «проводником в мире дизаена» будет разве что чувство меры, которое и раньше помогало (или нет) не запихивать всю логику в обработчики и следить за их отстегиванием, когда не нужны. Ну там, «трехслойка» по минимуму. Или напишешь в итоге свой домашний MVC/MVP СБИШ. Что касается многоокониевого лейаута, классического MDI в авалонии из коробки нет — «лучшее приближение» — доковые фреймворки и «упрощенные диалоги» с awesome авалонии на гитпохе. Ну или портировать некоторые наработки с того же WPF.

Подозреваю что обычно авалонию после WPF берут

Ну, меня задолбало «со-портить» портянку код-бехайнда прототипа, оставленного предшественником, «дистанцировавшимся от проекта», пришлось разобраться. А так — у меня дотнет активно был в 2010м году и в основном бэкэнд :) Прежний арбайтодатель с «мароканскими» облаками и бельгийскими заказчиками «с визгом отмежевался». Пришлось вспомнить шарп для местного. Так что щас — планшето-морды для встройки с сетевым клеем на том же дотнете и кастомным байто-сексом по RS485. Пишешь на X86, вкатываешь на ARM — и ЗБС. Не так «почетно» как у дидов из соседнего отдела на ассемблере, но и... не 100500 человеко-лет дебага, как у них же.

slackwarrior ★★★★★
()
Последнее исправление: slackwarrior (всего исправлений: 1)
Ответ на: комментарий от anonymous

Некоторая схемо-техническая кастомизация вокруг «импортозамещенных» рокчипов :) Для приложения все выглядит как местами йоктаный линукс с несколькими tty, в которые можно спамить байтиками и получать в ответ спам байтиками. Для юзера — пальцетыкательный интерфейс. Ну, еще рядом можно светодиодиками помигать и пищалками попищать. Приложуху с мозгами для конечных узлов можно отладить вообще на любом компе через socat и pty. Электроникой занимаются специально обученные электроники с импортозамещенными динрейками и «не-фениксовскими» корпусами. У них еще «не-STM32» импортозамещается на некоторых клонов.

slackwarrior ★★★★★
()
Последнее исправление: slackwarrior (всего исправлений: 1)
Ответ на: комментарий от anonymous

Ну кокой в ж... мауи или маргарин на линуксе :) выбор какбэ очевиден. Все остальное недалеко ушло от «кроссплатформы»(тм) времен ванильного дотнета, который щас .NET Framework. Между версиями венды. А теперь этот их мауи «винда + андроед с огрызком», потому что «ололо, Мигелюшка продался!» и обмазались маргарином, «объяли и расшарили». Конешшшно, авалония.

slackwarrior ★★★★★
()
Последнее исправление: slackwarrior (всего исправлений: 2)
Ответ на: комментарий от anonymous

Так дай обратную связь. Как оно? И вы покупали (winform) или на free версии?

Так на, возьми ее скорей. Для тыкания заскорузлыми пальцаме в промышленных масштабах в плоншеты бесплатной хватает за глаза и за уши. А разметка с биндингами плюс-минус везде одинаковая.

slackwarrior ★★★★★
()