MVVM открытие вторичного окна с передачей параметра в конструктор ViewModel06.06.2025, 09:22. Показов 2621. Ответов 39
Добрый день.
Тема наверняка избита, поэтому заранее прошу сильно не пинать. Если что, то я честно искал инфу и на форуме, и вообще. Проблема, которую мне хотелось бы обсудить: это открытие вторичного окна в паттерне MVVM с передачей через конструктор ViewModel параметра. Алиса говорит, что сделать это используя XAML невозможно. Значит надо это делать как-то иначе. Вариантов решения я нашёл аж три: 1. Создание сервиса или фабрики, который создаёт и окно, и связанную с ним VM, а при необходимости может даже инжектить объекты в VM. 2. Использование code-behind и свойств окна. 3. Использование ObjectDataProvider. Но всё равно возникает трудность с передачей параметра, т.е. нужен прокси-объект, который будет предоставлять параметр извне. В ходе недавнего обсуждения в этой теме я принял решение вынести проверку критически важных настроек приложения непосредственно в App.xaml.cs. И вот тут вопрос этой темы встал остро. Дело в том, что VM окна настроек, которое я планирую показывать в случае обнаружения ошибок в критически важных настройках, должна получить некий сервис. Логично чтобы это выглядело так Кликните здесь для просмотра всего текста
В данном примере подразумевается, что создание VM происходит в xaml. В данном случае нет внедрения в VM окон ничего хотя по заданию это должно происходить. С учётом того, что App видит все слои MVVM можно изменить код так: Кликните здесь для просмотра всего текста
Насколько это правильный подход для MVVM? И главный нюанс, который не даёт покоя: если на старте программы проверить настройки не проблема, то в ходе работы и в случае изменения настроек, надо реконфигурировать практически всё приложение. При этом у нас есть VM главного окна из которой надо открывать вторичные окна с передачей в их VM сервисов, а это уже намного сложнее. Как же это делается? По варианту №1? Если да, то к какому слою в паттерне MVVM относится сервис знающий и об окнах, и об их VM, и, возможно, об модели?
0
|
|||||||||||
| 06.06.2025, 09:22 | |
|
Ответы с готовыми решениями:
39
Mvvm ViewModel в ViewModel
|
|
|
|
| 06.06.2025, 22:25 | |
|
Uswer, честно, у меня были точно такие же проблемы. Но, как-то разрешились, и(!) даже без особого задавания вопросов на форуме. Все почему - потому что слушал и изучал примеры более опытных коллег:
Добавлено через 1 минуту Wolfdp Элд Хасп kolorotur ...
0
|
|
| 06.06.2025, 22:30 [ТС] | ||
|
0
|
||
| 06.06.2025, 22:38 [ТС] | ||
|
Добавлено через 57 секунд Не по теме: Давай флидуть будем поменьше. Я тоже постараюсь себя сдерживать. Добавлено через 3 минуты Кстати, что по вопросу: И как часто меняется фреймворк фронта?
0
|
||
|
|
|||
| 06.06.2025, 22:40 | |||
![]() Добавлено через 1 минуту
0
|
|||
|
|
|||||||||||||
| 06.06.2025, 23:35 | |||||||||||||
|
Для начала, в слой "view-model" входять непосредственно эти самые %Name%ViewModel, а также ICommand. Все действия от пользователя выносятся в ICommand. Вызов окна настроек -- тоже действие пользователя. %Name%ViewModel -- это больше для отображения информации, связи вводимых данных через Binding и размещения этих самых ICommand на View опять же через Binding (логику тоже можно закидывать, но стоит избегать такого). Теперь разбираем непосредственно реализацию ICommand -- это обычный класс (можно и структуру, но это бессмысленно). А значит мы можем в него прокинуть любой внутренний сервис в виде interface. В нашем случае скажем это
Теперь сама реализация IWindowService
new в идеале должны происходить либо в ioc-container, либо в factory. Если гляните пример от Andrey-MSK, то там есть сначала проверка что окно уже не открыто путём перебора Application.Current.Windows (удобно, но в идеале стоит в самом IWindowService хранить это значение), и саму view-model подразумевает создавать на внешнем коде (осуждаю, но это тема больше для холивара). Плюс россыпь MessageBox.Теперь представим что вам вместо окна нужно показать UserControl на MainWindow. ViewModel, ICommand -- всё это остается без единого изменения. В View вы тупо копируете весь xaml из windows в usercontrol. Меняете в WindowService реализацию метода ShowSetting. Вы только что сделали рефакторинг приложения за 5 минут без напряга и на 146% уверены что ничего не сломали (тестировать всё равно придётся). Не по теме: Замечу что всё это в целом можно провернуть и без MVVM и DI. Просто создать отдельный класс, который будет делать ShowSettings, и прям его без всяких интерфесов скажем через static singeltone дергать тупо по Button.Click прям в code-behind. Но для таких "простых" мувов нужно иметь адски правильное представление об общей архитектуре, т.к. любой шаг в сторону -- и все начинает ломаться. Поэтому пишут "сложно". Ну и поддерживать такое не очень удобно, даже в одно лицо. Возможно проблема не столько в MVVM, сколько в том что нет чёткого представления как разделить так, чтобы оно работало независимо друг-от-друга, но можно легко было соединить в единый организм. Не уверен что это можно выучить по книжкам не набив шишки на практике. Добавлено через 3 минуты На либе MS свет не сошёлся, есть всякие Autofac, Ninject, Spring.Net и ещё наверное с десяток.
2
|
|||||||||||||
|
Модератор
|
||
| 07.06.2025, 13:49 | ||
|
Здесь две разные задачи. 1) Академическая по изучению WPF, MVVM и т.п. 2) Создание приложения для распространения. В первом случае использование своих кастомных реализаций INPC, команды, внедрение зависимостей вполне оправдано.
1
|
||
|
Модератор
|
||||||||
| 07.06.2025, 20:40 | ||||||||
|
В WPF (любой XAML платформе) привязки внедрены уже как основной способ связывания UI элементов с источниками данных. Хоть использование привязок не является обязательным, но их использование очень просто и не вызывает затруднения даже у начинающих. Но привязки потянули за собой и более строги требования к архитектуре приложения: для привязок нужны правильно подготовленные источники данных. Как оказалось, даже для многих опытных пользователей их знания ООП архитектуры были формальны и на практике вызвало достаточно большие сложности в реализации MVVM. Но из моего личного опыта, те кто писал Формы с правильной реализованной архитектурой MVP, никаких сложностей с переходом на MVVM не испытывал. 2) Что вы имеете ввиду за сложности с присоединёнными свойствами - воще, не понял. Все DependencyProperty - это присоединённые свойства (Attached Property).Часть из них объявляется в DependencyObject и ограничивается использование в этом типе и его наследниках. Вот эти обычно называются Dependency Property (обратите внимание что здесь есть пробел).Другие могут объявляться в любом типе и использоваться любым типом DependencyObject. Вот их обычно называют Attached Property. В синтаксисе атрибут для обращения к Attached Property требует полного имени OwnerType.Property. Но к Dependency Property можно так же обращаться.Так как для Dependency Property известно, что они объявлены в этом типе UI элемент, то указывать тип не обязательно и можно использовать просто имя свойства.
3) "Остальное"... соглашусь, что "железная" часть платформы большинству разработчиков не интересна. Но само себе введение отдельного языка XAML для разметки GUI - это огромный шаг вперёд в сравнении с Формами. Ведь это только сам XAML, это все инструменты необходимые для того чтобы XAML было достаточно для компоновки интерфейса: "резиновость" элементов, Шаблоны и Стили элементов, Шаблоны Данных, Конвертеры, Анимации и мн. др. Попробовать разные варианты для получения опыта, знаний? Или предложенные варианты решения не устраивают по той или иной причине?
1
|
||||||||
|
Модератор
|
||||||||||||
| 07.06.2025, 20:57 | ||||||||||||
grid.Width не является Dependency Property, ни grid.SetColumn не является Attached Property.И то и другое это статические поля в типе:
DependencyObject.Set/GetValu(...).А CLR свойство и метод - это просто оболочки упрощающие для разработчика обращения к DependencyProperty.Добавлено через 7 минут Где находятся поля, хранящие значения свойств зависимости (DependencyProperty)?
1
|
||||||||||||
| 08.06.2025, 00:01 | ||
|
Не по теме:
0
|
||
|
Модератор
|
||
| 08.06.2025, 00:14 | ||
|
Есть удобный инструмент, с огромной поддержкой в среде разработчиков. Но почему в самой MS он как "нелюбимое дитя". Не хотят его развивать и всё! Вцепились в UWP и пытаются его продвинуть несмотря ни на что. UWP "не зашло" разработчиками. Платформа ужасно убогая в сравнении с WPF. Выдернули из него GUI и пытаются впихивают его под новым названием WinUI. Но как был убогим, так и остался.
0
|
||
| 08.06.2025, 10:58 [ТС] | ||||
|
К большому сожалению чистого MVVM у меня не получилось, возможно в следующем проекте буду делать это строже. Элд Хасп, с присоединяемыми свойствами всё хорошо в плане понимания. Я говорил о том, что одна строчка в XAML превращается в тучу строк C#. И как мне кажется именно поэтому мелкомягкие придумали XAML, т.е. чтобы избавить разработчика от жуткой рутины.
0
|
||||
|
Модератор
|
|||||
| 08.06.2025, 12:35 | |||||
|
UWP (и другие XAML) приходится использовать из-за отсутствия WPF на других платформах. И каждый раз как натыкаюсь на очередную "прелесть" тихо матерюсь. То что можно сделать на WPF "одной строкой" на UWP часто требует основательных "танцев с бубном". Единственно, что существенно добавили в UWP - это компилируемые привязки x:Bind.В WPF их тоже обещали добавить, но "воз и ныне там". Да, и за эти годы их актуальность стала уже почти нулевой. Они дают ускорение. UWP рассчитан на различные устройства. И на слабых устройствах - это ускорение могло давать существенный выигрыш. Но за 15 прошедших лет изменилось понимание что такое "слабое устройство". Сейчас даже на самых слабых устройствах никакого реального преимущества компилируемые привязки в сравнении с обычными не дадут. Выявить разницу удастся только какими-то синтетическими тестами. Добавлено через 4 минуты Для них огромный плюс UWP - это распространении этих приложений через Microsoft Store. Этот плюс перевешивает все недостатки вместе взятые. Голоса инженеров, разработчиков решающей роли не играют. Добавлено через 11 минут Это задача уровня Бизнес Логики и App. Чтобы упорядочить всю эту кашу и приходится использовать какие-то паттерны, типовые решения, распространённые фреймворки и т.д. Но главное это умение "в голове" разделить большую задачу на мелкие, их на пошаговые алгоритмы, построить на всём этом какую-то адекватную архитектуру. Конкретно с настройками изменяющимися динамически - основа очень проста. Настройки для бизнес логики - это такие же данные как и все остальные. Если они меняются значит нужно какое-то уведомление об этом. Если меняются они только в рамках сеанса одного приложения, то локальный класс провайдер обслуживающий их. Если меняются в многопользовательском режиме, то уже, возможно, потребуется какая-то служба для отслеживания. В любом случае на уровне бизнес логики появляется какой-то объект поставщик данных (пусть и настроек). При изменении данных в нём поднимается событие. Потребители данных подписаны на поставщика и по событию обновляют своё состояние. Потребители могут быть любого уровня: Model, View, Controller, Presenter, ViewModel и т.д. Для Поставщика нет разницы кто потребляет его данные.
1
|
|||||
|
|
|||
| 08.06.2025, 16:00 | |||
|
В теории внутрянка должна быть настолько независима, что можно вытянуть и без радикальных изменений вставить например в WinForms. Я за ориентир обычно беру возможность вынести всё это добро в отдельную либу. Все силы в первую очередь должны идти на штатную работу приложения. Т.е. считаем что все сервисы сконфигурированы, всё подключается, всё работает. Далее тратим силы на то, что реально происходит с юзерами при работе с приложением. Например отсутствие связи с сервисом -- возможна ситуация и её стоит учитывать. Забыли указать сервис в конфигах -- уже маловероятно и тратить силы на то чтобы придумать как с этим работать не шибко нужно. Да и строго говоря обычный юзер пойдёт в техподдержку, а не будет решать своими силами.
0
|
|||
|
|
|
| 09.06.2025, 18:26 | |
|
Uswer, им нужно будет вбивать эти настройки самостоятельно, или это тоже ваша ответственность? Если ваша -- вынесите всё в конфиг файлы (причём можно задать нетипичное расширение, например *.sys), уберите окна настроек чтобы не провоцировать юзверей поиграть в админов и у вас резко поубавится работы.
Если адресса серверов таки должны вбивать пользователе -- вы не защититесь от "неправильных" значений никак, и валидация должна присутствовать много где. Типа стартуем сервис -- сначала проверяем что конфиги адекватны. Это же опять не уровень WPF.
0
|
|
| 09.06.2025, 18:26 | |
|
Как зарегистрировать ViewModel через Autofac, создав между ViewModel и нужным View DataContext связь?
Передача объекта во View из ViewModel (WPF/MVVM/Caliburn) Определить конструктор без параметров, конструктор с одним параметром, конструктор с двумя параметрами, деструктор Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык.
Возвращает он вот это:
https:/ / i. **********/ vqBWLe2. png
Нужную строчку в 3й колонке просто выдумал. .
Это. . .
|
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor.
Это. . .
|
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js.
В помощники взял Яндекс-Алису.
Было создано три зала на разные интересы.
исторические и ретро
сериал Хичкок. . .
|
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
|
|
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#.
Название изменил на ColorStep.
Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
|
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами:
- ВидТО (СправочникСсылка. ВидыТО);
- ВидГСМ. . .
|
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала.
Ниже прикреплён. . .
|
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F
Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU.
Опрашиваются регистры. . .
|