MVVM блокировка кнопки до валидации10.04.2025, 10:56. Показов 6184. Ответов 71
Метки нет (Все метки)
Добрый день.
Исходные данные: разработка в шаблоне MVVM, у некоего окна есть кнопка "ОК", к которой в xaml привязана команда из VM. Также на уровне VM делается валидация данных при помощи INotifyDataErrorInfo. При открытии окна кнопка "ОК" доступна для нажатия хотя дефолтные данные в окне не валидны. Кнопка блокируется если начать вводить не правильные данные, то есть кнопка реагирует только тогда, когда начинает работать механизм валидации. Вопрос в следующем: как при открытии окна сделать кнопку "ОК" недоступной для нажатия с сохранение её зависимости от CanExecute изменяемой при валидации? Добавлено через 5 минут Дополнительное пояснение. Допустим есть одно текстовое поле, которое не может быть пустым и эта проверка делается в VM, после чего устанавливается HasErrors, на который и реагирует кнопка. Но сразу после открытия окна поле пустое и если его не трогать оно также остаётся пустым (не валидным), но в этом случае HasErrors не устанавливается.
0
|
|
| 10.04.2025, 10:56 | |
|
Ответы с готовыми решениями:
71
Обработка валидации данных в слое VM (MVVM)
|
|
|
|
| 11.04.2025, 17:21 | |
|
proa33, в том то и вопрос - зачем тут эта 'другая' сущность...
Здесь вход в понимание валидации и активирования команд произошел методом от противного ("не с той стороны"). Сперва бы сделать нормальную модель всего этого, прочувствовать работу, а уж потом прикручивать сюда INotifyDataErrorInfo.
0
|
|
|
Модератор
|
|||
| 11.04.2025, 17:27 | |||
|
Такая реализация по умолчанию рассчитана на валидное состояние VM после инициализации полей. Uswer, это очень похоже на "обрезки" Community Toolkits.Если вам нужно "попроще и понятнее для себя", то лучше использовать что-то своё интуитивно понятное. Если вам нужно сделать "для работы", то лучше использовать какой-то распространённый фреймворк (тот же Community Toolkits) и все решения уже реализовывать его инструментами. Добавлено через 2 минуты Например, в public IEnumerable GetErrors(string propertyName) должна быть обработка string.IsNullOrEmpty(propertyName). При таком запросе должны возвращаться все ошибки по всем свойствам.
0
|
|||
| 11.04.2025, 20:26 [ТС] | ||||||
|
Ладно. Всем спасибо за участие, я как нибудь сам разберусь. Потрачу кучу времени, но разберусь. Считаю тему исчерпанной (мне всё понятно).
0
|
||||||
|
|
|||
| 11.04.2025, 20:52 | |||
|
Добавлено через 1 минуту Uswer, извини, но начинать надо не с этого.
0
|
|||
| 11.04.2025, 21:18 [ТС] | ||
|
Добавлено через 1 минуту Простой же пример: есть элементарная DTO, которую надо обрабатывать в коде (создавать новые экземпляры, изменять существующие). Вот прям на этих двух окнах покажи.
0
|
||
|
|
||
| 11.04.2025, 21:31 | ||
|
0
|
||
|
|
|
| 11.04.2025, 21:56 | |
|
Uswer, ну вот чистая критика того что на гит-хабе: я открыл, по диагонали посмотрел - вроде да, что-то должно работать. Но INotifyDataErrorInfo не там где надо - бросилось в глаза сразу. Да и вообще, зачем он тут нужен (пока). Далее, непонятно почему твою DTO рожает вью-модель..? Ну и прочие мелкие детали.
Суть то вопроса более узка: как запретить выполнение команд (деактивировать контролы) при некоторых условиях.. И когда этот момент станет ясен, можно переходить к более "крутым" фишкам, типа реализации INotifyDataErrorInfo.. Но ты это даже не понял, а сразу начал с потолка.. Твой проект нужно не исправлять, а переделывать, что требует чуть большего кол-ва времени чем есть в наличии конкретно сейчас. Но вскоре он разрешится, так или иначе. 3 человека тебе говорят одно и то же, но нет, надо блин упорствовать... Добавлено через 2 минуты P.S. Завтра попробую соорудить рабочий пример по этой теме. Но думаю, до этого времени уже Элд Хасп что-то толковое напишет и выложит.
0
|
|
| 12.04.2025, 00:08 [ТС] | ||||||||
|
Чтобы было понятно - то что на гите это не образец для подражания, это было сделано тяп-ляп, чтобы показать проблему. А то начался разбор на запчасти "это не там лежит", "то не то". Не по теме: Ё-моё, когда же отвечающие научатся слышать вопрошающего?! Да задача не соответствует показанному на гите, но ещё раз - на гите воспроизведение проблемы так, как её наблюдаю я сейчас. Но хочу от этого избавиться. Я же вроде бы писал Добавлено через 10 минут БД+самописный класс = Model в терминах шаблона MVVM. Теперь задача: нужно чтобы пользователь создал новую персону. Где родить экземпляр Person? Или, по твоему, для такой простой операции нужно нагородить километровую конструкцию кода в Model, чтобы что?
0
|
||||||||
|
1596 / 601 / 185
Регистрация: 05.12.2015
Сообщений: 970
|
|
| 12.04.2025, 00:41 | |
|
Uswer, Посмотри этот пример - переделал твой, это только один из вариантов. Может что пропустил - напиши проверим.
0
|
|
|
|
|||
| 12.04.2025, 00:45 | |||
|
Между делом, стандартный шаблон валидации уже накидал: где: - ничего лишнего (DTO) не создается; - кнопка добавления изначально не активна; - валидация происходит в реальном времени (при изменении свойств). Вывод причин невалидного ввода - ну, могут вариантов 10 на вскидку предложить, всяких разных. В том числе и через NotifyDataErrorInfo.
0
|
|||
|
Модератор
|
|||||||||||||||||
| 13.04.2025, 19:36 | |||||||||||||||||
|
Основные моменты. 1) Person - DTO только для чтения. Создаются экземпляры в Модели. 2) Модель с локальным кешем и функцией добавления персов в неё. 3) VM добавления создаётся MainVM специальным методом с передачей в него Модели:
CommandManager.RequerySuggested.6) Валидация происходит без запоминания. Такая реализация не оптимальна в рантайм, но зато намного упрощает понимание как же она работает и облегчает обучение. Добавлено через 29 секунд
Uswer, сделал ещё фиксацию "Добавлен вывод всех ошибок при наведении на кнопку."
0
|
|||||||||||||||||
|
Модератор
|
|||||||||||
| 13.04.2025, 21:21 | |||||||||||
|
Uswer, по последней фиксации
7b4cac1404cfaad4aa3e5bba397f83aa39218cc5 буду писать комменты сразу здесь по мере проверки кода.Добавлено через 1 минуту
Добавлено через 2 минуты
0
|
|||||||||||
| 13.04.2025, 21:30 [ТС] | |||
|
0
|
|||
|
Модератор
|
|||||||||||
| 13.04.2025, 21:50 | |||||||||||
1
|
|||||||||||
|
Модератор
|
|||||||||||||
| 13.04.2025, 22:06 | |||||||||||||
|
Добавлено через 19 минут
Лишний мусор и лишние проверки без всякой необходимости в этом. HasErrors прокидывать через INPC. Часто на это свойство завязывают какие-то триггера или привязки.А без INPC они работать не будут. Добавлено через 1 минуту Uswer, не понял зачем вам этот интерфейс IValidatable?Добавлено через 5 минут Внешняя регистрация правил валидации? Если этот интерфейс имеет обобщённый характер, то результат валидации (ValidationRes.ErrorMessage) это не всегда строка. Там может быть любой объект. Добавлено через 5 минут
А словарь _errors рассчитан на хранение множества ошибок по каждому свойству.Следовательно, либо метод Validate<T> реализован не полно, либо словарь ошибок избыточен.Добавлено через 3 минуты Полный код с моими исправлениями
0
|
|||||||||||||
|
Модератор
|
|||||||||||
| 13.04.2025, 22:10 | |||||||||||
|
Uswer, Теперь к PersonViewModel переходим.
Добавлено через 1 минуту
PersonDTO мутабельный, то делать его публичным нельзя. Это делает возможным напрямую изменение его свойств потребителями. И тогда никакие уведомления об изменениях не сработают.Добавлено через 1 минуту
0
|
|||||||||||
| 13.04.2025, 22:10 [ТС] | |
|
0
|
|
| 13.04.2025, 22:10 | |
|
Избежать одновременного выполнения LostFocus и команды кнопки MVVM
Добавление кнопки в форме с кнопки и смена фона новой кнопки Временное отключение валидации Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Саморегулирующийся социальный контракт для сервера cross-section.
Hrethgir 14.08.2026
С кодом конечно таких глубоких размышлений пока не было, впрочем я уже привык к алгоритмизации. Суть предмета записи: снова в диалоге с нейросетью (я взял пока себе ник для учётки админа - Rector). . . .
|
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет:
1. Использовать системное время и дату,
2. Есть возможность вводить время и дату вручную.
3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
|
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber.
Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
|
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео:
https:/ / vkvideo. ru/ video-240781534_456239017
YouTube:
eY5-5PyI9NM
Текстовая версия
|
|
Неделя из жизни имитационной модели склада: мои кривые руки растут, откуда надо
anaschu 10.08.2026
Неделя из жизни имитационной модели склада: как я почти написал неправильную логику и что с этим делать
Работаю сейчас над учебно-рабочим проектом: строю в AnyLogic имитационную модель процессов. . .
|
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства.
Родственных связей существует 8 ступеней, такие как:
p - отец
P - мать
q - муж
Q - жена
b - брат
B - сестра
s - сын
S - дочь
|
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире.
Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
|
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С.
Задача:
Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
|