|
264 / 153 / 33
Регистрация: 29.06.2019
Сообщений: 1,554
|
||||||||
Где лучше в MVVM реализовать дополнительную логику?25.09.2025, 19:46. Показов 8775. Ответов 118
Метки нет (Все метки)
мне почему-то кажется, что это не проблема, а как раз и задумано было, чтобы можно было переназначать свойства в зависимости от нужного (например, цвет текста при value>1000, условно говоря) - вот и вынесли это DP в отдельный класс... а за пример реализации и использования в XAML - спасибо!.. ? только в каких случаях это DP подключают обычно?.. как по мне, так Styles и Templates и даже Converters - нормальные внутренние (для объекта) свойства, дальше которых уже и придумать нечего (с практической точки зрения) чтобы захотеть подключать из-вне класса ещё и DP за гранью всего, что можно задать и в объекте...
0
|
||||||||
| 25.09.2025, 19:46 | |
|
Ответы с готовыми решениями:
118
|
|
|
|||||||
| 29.09.2025, 09:17 | |||||||
![]() Добавлено через 5 минут JeyCi, Вот ещё момент. Если команда зависит от состояния коллекции, например от свойства Count, то CanExecute проверяется вот так
0
|
|||||||
|
|
||
| 29.09.2025, 09:26 | ||
0
|
||
|
264 / 153 / 33
Регистрация: 29.06.2019
Сообщений: 1,554
|
||||||||
| 29.09.2025, 19:35 [ТС] | ||||||||
|
а что насчёт MVVMLight? кто-нибудь юзал?
P.S. в 2х (3х) словах - по теме: 1) валидация в VM : DependencyObject - PropertyChangedCallback и CoerceValueCallback ... обработка DependencyProperty.UnsetValue ... 2) чтобы связать события (которые не определены для элементов wpf) с командами - Microsoft.Xaml.Behaviors.Wpf P.P.S.
![]() P.P.P.S. и пример App:
0
|
||||||||
|
|
||
| 29.09.2025, 19:38 | ||
|
Если проводить аналогию с asp.net MVC, то там толстые контролы считали чуть-ли не антипатерном.
0
|
||
|
264 / 153 / 33
Регистрация: 29.06.2019
Сообщений: 1,554
|
|||||||||
| 29.09.2025, 19:43 [ТС] | |||||||||
3) про ICommand - а эта реализация из Prism по-лучше? (чем та слабенькая) Кликните здесь для просмотра всего текста
0
|
|||||||||
|
Модератор
|
||||
| 29.09.2025, 20:04 | ||||
|
Есть некая коллекция отражающая многопользовательскую БД. Коллекция обновляется по событиям модели поднимающимся при изменении БД, в том числе и другими пользователями. В GUI есть кнопка для добавления сущности. Но если равная сущность уже есть в БД, то кнопка должна быть Disabled. Где надо реализовать CanExecute команды кнопки? И когда подымать CanExecuteChanged этой команды? Но она не обеспечивает потокобезопасность для WPF. RaiseCanExecuteChanged подымает CanExecuteChanged. Это событие в WPF обязательно должно подыматься в UI потоке. Поэтому и метод RaiseCanExecuteChanged должен вызываться только в UI потоке. А для этого придётся или в VM передавать контекст синхронизации UI потока, либо в View добавлять буфер для маршалинга CanExecuteChanged в UI поток.
0
|
||||
|
264 / 153 / 33
Регистрация: 29.06.2019
Сообщений: 1,554
|
|
| 29.09.2025, 20:14 [ТС] | |
|
p.s.
ну и thread-safe Observable Collection <ListBox Grid.Row="1" ItemsSource="{Binding Items.AsObservable}" />
0
|
|
|
|
||
| 29.09.2025, 21:06 | ||
|
Я скорее про то что такой "минимализм" инструмента возможно даже хорошо. Очень часто со временем скатываешься к тому что BL просачивается во все щели: городишь километровый SP ради оптимизации, в эндпоинтах сервиса вместо лаконичного вызова ServiceName.Method тоже разворачивается простыня... А так сам инструмент будет мотивировать не раздувать ViewModel.
0
|
||
|
Модератор
|
|||
| 30.09.2025, 00:06 | |||
|
Сама же коллекция сущностей в VM. БД удалённая многопользовательская, если на "каждый чих" (в этом случае вызов CanExcute - который может вызываться часто) обращаться у этой БД, то чёрт его знает какие лаги будут. Можно, конечно, коллекцию сущностей разместить в модели. По сути это выйдет локальный кеш, в таком случае. Но зачем? Для того чтобы удобнее было CanExcute вызывать? Но это как бы не функция Модели заботится что и как удобнее сделать для View. Это полностью зона ответственности ViewModel. Добавлено через 10 минут У каждого слоя своя зона ответственности. Зона Модели- это работа с предметной областью. Зона ViewModel - предоставить View в удобном виде функционал Модели. В моём примере, забота о соcтоянии команды - это полностью область зона ответсвенности View Model. Хранение списка - тоже зона ответственности ViewModel. Модель отвечает только за запросы к БД. Даже необходимость наличия списка для View на уровне Модели неизвестна. В целом. Есть разные задачи. И в них могут потребоваться разные реализации. Реактивное программирование - это очень мощный инструмент И он не привязан к конкретному слою. Его можно использовать в любом месте от Модели до View и даже в App. Другой вопрос, что РП несколько отличается от принятого в .Net стиля реализации, поэтому осваивать его непросто. Особенно с учётом особенностей его реализации в различных пакетах. Освоить его "на всякий случай", просто для получения опыта - не выйдет. В таком случае реализации на нём будут наоборот казаться более сложными, непонятными.
0
|
|||
|
|
||||
| 30.09.2025, 01:33 | ||||
|
В любом случае это под капотом модели, она же является основополагающей, а не ViewModel. Как там по факту всё это реализовано -- вообще фиолтетово. Грубо говоря у нас есть задача "отслеживать состояние модели". Варианты правильного решения для model: - иметь event который срабатывает когда меняется её состояние (сейчас не важно как мы отслеживаем это, главное что меняется) - метод регистрации callback-а Т.е. у нас общая задача "отслеживать состояние модели" имеет фактическое решение. Вариант сделать неправильно: - прям в самой ViewModel запускать Task который будет раз в интервал опрашивать БД и смотреть текущий статус и т.д. Вот это уже означает что мы логику зафигачили в ViewModel. И на таком простом примере в целом понятно что у нас в Model должен быть механизм отслеживания, а не ViewModel получать модель, и самостоятельно начинать отслеживать её. Когда кода побольше, то уже сложнее найти ту середину, когда на каждое действие не делать отдельный метод в BL, но и не раздувать код в ViewModel.
0
|
||||
|
264 / 153 / 33
Регистрация: 29.06.2019
Сообщений: 1,554
|
|||||
| 30.09.2025, 09:01 [ТС] | |||||
|
есть разные способы послать EventArgs в Command (реализованные в различных фреймворках и пакетах) ================
Маршрутизация команд в принципе вся от ICommand (XamlUICommand Класс):
Добавлено через 2 минуты вопрос, наверно, лишь в разделении той бизнес-логики, которую надо показать, и той её части, которую надо хранить и вернуть
0
|
|||||
|
Модератор
|
||
| 30.09.2025, 09:20 | ||
|
В том числи из службы прилетают эвенты при изменении БД одним из пользователей. Локальное решение - это тонкий клиент и в плане WPF+MVVM мы рассматриваем его. Модель тонкого клиента отвечает только за трансляцию запросов к БД от потребителей, возврата им ответов и трансляцию эвентов службы в эвенты .Net. Нужно ли хранить список сущностей потребителям - Модель "не знает". Нужно ли валидировать запрос на добавление сущности перед его отправкой в службу - Модель не знает. Модель просто отправляет запрос на добавление и потом ожидает ответа. Допустим, этот ответ требует времени 10 секунд. Результат ответа - это добавленная сущность или ошибка и соответствующий эвент. Может ли Модель (через службу) проверить валидность добавляемой сущности? Может, конечно. Но!.... как выше писал, предположим обработка запроса занимает 10сек. Рационально ли вешать CanExcute на такой метод? Нет конечно - при каждом клике будет лаг в 10 сек. Как реализовать: 1) Не делать валидацию добавляемой сущности при её изменении в GUI. После клика по кнопке отправлять запрос на добавление и в случае отказа выводить ошибку. Вариант возможен? Конечно. Но хочется предварительную быструю валидацию, чтобы не тратить время пользователя на ошибочные запросы. 2) Можно ли сделать кеш в модели и по нему проводить быструю валидацию? Можно. Но Модель не знает нужно ли это потребителю. Пример такой реализации - это локальный кеш в DbContext. При необходимости он загружается данными БД. Потом прокидывается его ObservableCollection потребителям Модели. По событиям службы этот кеш можно обновлять. Работет Loacal DbContext тоже со своими нюансами, там тоже не так всё просто. Но в целом для направления реализации понятно. Но не используется DbContext, то стоит ли его реализовывать самостоятельно, если при этом не известно нужен ли потребителю и в каком виде? Общая реализация - будет достаточно сложна, а частная - требует "знаний" о конечном потребителе (View). 3) Можно сделать над общей Моделью ещё одну оболочку Модели под конкретных потребителей, которым это надо. В этой НадМодели и будет происходить кеширование и быстрая валидация. 4) Это последний вариант. В нём кеширование и быстрая валидация - это функция ViewModel. Можно его представить как объединение ViewModel и НадМодели из 3-го варианта. Все 4 варианта (наверное можно представить и большее их количество) имеют "право на жизнь". У каждого есть свои + и -. Если условия меняются. Например валидация через службу занимает миллисекунды, то первый вариант вполне нормальный и можно не заморачиваться. Хотя список в ViewModel в этом случае всё равно понадобится. Второй вариант может потребоваться для какой-то библиотечной реализации рассчитанной на общее широкое применение. Третий от четвёртого отличается только выделением определённой логики из ViewModel. Я, честно, для одноразовой реализации не вижу смысла так заморачиваться. Возможно при каких-то условиях ТЗ, с учётом поддержки и модернизации приложения в будущем - действительно стоит так сделать.
0
|
||
|
Модератор
|
||
| 30.09.2025, 09:26 | ||
|
Простой пакет. Сейчас уже прекращена его поддержка и модернизация. Но наверное самый загружаемый из пакетов предназначеных для создания ViewModel. Создавался этот пакет частью команды участвовавшей в разработке WPF. Потом был отпущен в "свободное плавание". Очень активно использовался (и возможно используется) в академической среде США (и думаю других западных стран) при обучении студентов WPF. Сейчас перестал развиваться не потому что устарел, а потому что "достиг совершенства". Всё что нужно для его концепции - там и так уже есть. А превращаться в конкурента коммерческих, "взрослых" фреймворков изначально не было задачи.
0
|
||
|
|
||
| 30.09.2025, 09:29 | ||
|
JeyCi, Если уж совсем по простому, то команда (ICommand) это просто некая штука, которая может быть где угодно и просто вызывает некие методы по определённым действиям и условиям.
В MVVM её принято объявлять во ViewModel, далее она взаимодействует по DI с нижележащими слоями - Model, Service, получает/передаёт данные, подготавливает их для чего-то. Ещё команду можно сделать напрямую во View, но только в том случае, если она не проникает ниже VM. То бишь вызвать метод VM она может, но взаимодействовать с Model уже нет.
0
|
||
|
Модератор
|
||||
| 30.09.2025, 09:36 | ||||
|
В некоторых случаях имеет "право на жизнь". Валидация свойств отвечает за корректное функционирование UI элемента (Custom Control обычно). Валидация биндингов - за предварительную валидацию пользовательского ввода. В плане MVVM чаще всего реализуется совместно с интерфейсами IDataErrorInfo или INotifyDataErrorInfo. Первый проще, но считается устаревшим. Добавлено через 3 минуты Но сейчас принято всё выносить из Code Behind. DispatcherUnhandledException - не все исключения отлавливает. И нужно правильно эти исключения выкидывать, чтобы было достаточно информации для их обраболтки. Обычно сюда выкидываются только исключения приводящие к закрытию приложения.
1
|
||||
|
264 / 153 / 33
Регистрация: 29.06.2019
Сообщений: 1,554
|
||
| 30.09.2025, 09:39 [ТС] | ||
|
0
|
||
|
Модератор
|
||
| 30.09.2025, 09:40 | ||
|
Например после клика кнопки "Добавить" надо получить результат было добавление или нет. В первом случае закрыть окно добавления, а во втором вывести предупреждение и продолжить редактирование. Команда вызвsает только void метод. Поэтому один из способов решения такой задачи - это передача сложного аргумента в метод и анализ переданного аргумента, по завершению метода.
0
|
||
|
264 / 153 / 33
Регистрация: 29.06.2019
Сообщений: 1,554
|
|
| 30.09.2025, 09:40 [ТС] | |
|
0
|
|
|
Модератор
|
|
| 30.09.2025, 09:41 | |
|
Я пока отчаливаю - работа.
Дальше вечером посмотрю, если будет время.
0
|
|
| 30.09.2025, 09:41 | |
|
MVVM бизнес логика и Model
Как реализовать работу нескольких окон под шаблоном MVVM? Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Сегодня суббота, 22.08.2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины.
zorxor 22.08.2026
Сегодня суббота, 22. 08. 2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины. Кто Я, откуда Я пришел и куда Я иду? Эти вопросы не оставляют меня ни на секунду. Жизнь на планете Земля. . .
|
Жизня: рисунок укладки багажа, сделанный клодом
anaschu 21.08.2026
Сделал 15 снимков, он по снимкам сделал схему.
|
Был там один разговор по поводу свободы в материальном мире.
kumehtar 19.08.2026
Суть: рассматривается живое существо, оказавшееся внутри довольно странной системы (этого мира) и пытающееся обустроить в ней свой кусок пространства.
Жизнь действительно предъявляет каждому. . .
|
Когда логика программы не спасает от человеческих ошибок
Maks 18.08.2026
В последнее время всё чаще и чаще сталкиваюсь с таким явлением, как абсолютная невнимательность (или глупость) пользователей. Проявляется это чаще всего на работе в коллективе. Допустим, человек с. . .
|
|
Лето уходит
kumehtar 17.08.2026
|
Мысли в слух
kumehtar 17.08.2026
Забавно, насколько сейчас стала доступна информация. Например о магии, духовном развитии, медитациях, и других подобных направлениях, ранее зачастую тайных, передаваемых от учителя к ученику. Хотя. . .
|
Перемещение строк из ТЧ в другой документ с учетом текущего пробега
Maks 17.08.2026
Реализация из решения ниже выполнена на примере нетипового документа "Автозапчасти", с ТЧ "Шины".
За основу взят алгоритм отсюда: https:/ / www. cyberforum. ru/ blogs/ 359708/ 10838. html
Задача: . . .
|
Саморегулирующийся социальный контракт для сервера cross-section.
Hrethgir 14.08.2026
С кодом конечно таких глубоких размышлений пока не было, впрочем я уже привык к алгоритмизации. Суть предмета записи: снова в диалоге с нейросетью (я взял пока себе ник для учётки админа - Rector). . . .
|