Несколько ViewModel одного окна с INotifyDataErrorInfo12.08.2025, 11:40. Показов 988. Ответов 14
Метки нет (Все метки)
Добрый день.
У окна есть своя ViewModel, однако внутри окна есть несколько UserControl со своими ViewModel. Все ViewModel реализуют INotifyDataErrorInfo. Проблема - при наличии ошибок валидации в ViewModel принадлежащих UserControl ViewModel окна не знает о них. Логично чтобы ViewModel окна знала о всех ViewModel UserControl-ов для того, чтобы она имела доступ к ошибкам в них. Будет ли правильным, что ViewModel окна будет порождать ViewModel UserControl-ов и иметь на них ссылки? Или есть вариант по лучше? В настоящий момент ViewModel UserControl-ов создаются в слое View и там же связываются. Пример описанного взаимодействия можно посмотреть в ответе №1 тут: ru .stackoverflow .com/questions/634115/Как-в-wpf-менять-содержимое-окна
0
|
|
| 12.08.2025, 11:40 | |
|
Ответы с готовыми решениями:
14
Mvvm ViewModel в ViewModel |
|
1857 / 1363 / 429
Регистрация: 10.06.2011
Сообщений: 2,136
|
|||
| 12.08.2025, 13:38 | |||
|
Если хотите проще и по MVVM, то создавайте ViewModel внутри ViewModel. Прокидывайте информацию о валидации по событиям (члены класса event). Для справки: если требуется более высокий уровень, то есть библиотека PRISM. Но там взаимодействие между ViewModel организовано сложнее - через IEventAggregator. А регистрация View\ViewModel в нудные участки окна происходит через регионы.
2
|
|||
| 12.08.2025, 14:02 [ТС] | ||
|
За ответ спасибо.
novikov.ea, прокомментируйте ваше утверждение пожалуйста.
0
|
||
|
1857 / 1363 / 429
Регистрация: 10.06.2011
Сообщений: 2,136
|
||
| 12.08.2025, 14:50 | ||
|
1) Это работает 2) Это просто Если вы делаете приложение из одного окошка, то этот подход работает. Но, если нужно делать более сложное приложение или большего размера, то такой подход будет нарушать MVVM, т.к. нужно 1) Передавать зависимости в конструкторы ViewModel. Как вы создадите ViewModel внутри View, прокинув в конструктор все требуемые зависимости? 2) Менять содержимое окна (заменять вьюхи). Чтобы заменить view по MVVM надо в свойство задать другую ViewModel, а о ней знает только сама View
1
|
||
|
Модератор
|
||||||||
| 12.08.2025, 17:29 | ||||||||
|
В пример на stackoverflow ru сразу написано :
Теперь по существу вашего вопроса. Если я правильно понял, то окно разбито на несколько регионов. Разбивка статична, у каждого региона своя жёстко заданная UserControl'ом компоновка. У каждого региона и своя VM. Окно, его VM и VM регионов живут весь сеанс приложения. Логика основной VM должна зависеть от логики VM регионов. В такой задаче оптимальным было бы создание рабочий каркас приложения в духе VM регионов в основной:
0
|
||||||||
| 12.08.2025, 18:24 [ТС] | |||
|
Всё равно не понимаю как в VM окна передавать все ошибки "дочерних" VM. Дело в том, что в момент создания некоторые VM проводят валидацию свойств. Таким образом даже подписавшись на событие ErrorsChanged дочерних VM я получу извещения только об ошибках возникающих в процессе взаимодействия с пользователем, а те что были на момент создания VM остаются незамеченными.
Мои варианты решения проблемы: - Либо надо делать общую VM со всеми валидируемыми данными, тогда проблем нет, но она становится адски перегруженной. - Либо надо изобретать свой EventAggregator или разбираться с PRISM, но ни то, ни другое делать не хочется ради одного окна и пары-тройки UserControl. Добавлено через 1 минуту Добавлено через 38 минут
0
|
|||
|
1857 / 1363 / 429
Регистрация: 10.06.2011
Сообщений: 2,136
|
||||||
| 12.08.2025, 19:26 | ||||||
|
В простом варианте реализации дочерние ViewModel должны иметь свойство IsValid и событие IsValidChanged
0
|
||||||
| 12.08.2025, 19:35 [ТС] | |||||||
0
|
|||||||
|
Модератор
|
||||||||
| 12.08.2025, 23:53 | ||||||||
|
Это детали реализации и не принципиально. Один из возможных вариантов:
0
|
||||||||
| 13.08.2025, 08:20 [ТС] | ||||||||||||
|
VM окна
VM UserControl-а
0
|
||||||||||||
|
|
||
| 13.08.2025, 08:30 | ||
|
0
|
||
|
1857 / 1363 / 429
Регистрация: 10.06.2011
Сообщений: 2,136
|
|||
| 13.08.2025, 09:02 | |||
|
0
|
|||
|
Модератор
|
||||||||||||
| 13.08.2025, 09:35 | ||||||||||||
|
Конкретно в вашей задаче, ленивая инициализация не решает никаких задач, но значительно усложняет коннект. Я не знаю вашу реализацию BaseViewModel, поэтом на всякий случай уточняю, некоторые моменты на типичной реализации:
0
|
||||||||||||
| 13.08.2025, 11:52 [ТС] | |||
|
Элд Хасп, да вы провидец!
Добавлено через 7 минут Решено. Всем участникам обсуждения - большое спасибо! Решение. Я написал очень простой агрегатор событий ErrorsChanged. Он создаётся в MainVM и передаётся во все UserControlVM, где в конструкторе выполняется регистрация отправителей события. Всё. Теперь события ErrorsChanged возникающие на любой стадии жизни UserControlVM прокидываются в MainVM, где и обрабатываются.
0
|
|||
|
Модератор
|
|
| 13.08.2025, 13:16 | |
|
Uswer, вы не поняли логику моего примера.
Валидация свойств дочерних VM - это функция самой дочерней VM. Основная VM валидирует свои свойства. А так как одним из свойств является экземпляр дочерней VM, то проверка его валидности это задача основной VM. Уточняю. Проверка валидности экземпляра, а не свойств экземпляра. Поэтому в моём примере метод проверки валидации проверяет наличие ошибки и если она есть, то агрегирует все ошибки экземпляра. В свойства экземпляра логика не лезет.
1
|
|
| 13.08.2025, 13:16 | |
|
Помогаю со студенческими работами здесь
15
Как зарегистрировать ViewModel через Autofac, создав между ViewModel и нужным View DataContext связь? (GalaSoft.MvvmLight) В одном окне используются 2 ViewModel. Вылетает исключение при создании окна
Как сделать при нажатии на кнопку (отправлении команды во ViewModel) Cursor.Wait у окна? Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
||||
|
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта
Симптом:
После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
|
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
|
Новый ноутбук
volvo 07.12.2025
Всем привет.
По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне:
Ryzen 5 7533HS
64 Gb DDR5
1Tb NVMe
16" Full HD Display
Win11 Pro
|
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
|
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
|
|
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов
На странице:
https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/
нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
|
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов.
. . .
|
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
|
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
|
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут.
В век Веб все очень привыкли к дизайну Single-Page-Application .
Быстренько разберем подход "на фреймах".
Мы делаем одну. . .
|