|
ValidationRule+IValueConverter: сброс source в null при ошибке+отображение ошибки - как?
|
|||
---|---|---|---|
#18+
Есть вот такой схематичный код: Код: xml 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66.
Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66.
Работает он вполне нормально, но есть одно но: если сначала в текстбокс ввести правильное значение (например, 123 - связанное свойство примет значение 123), потом выделить весь текст, и начать вводить неправильное значение (например, qqq), то соответствующая ошибка валидации будет отображена, но связанное свойство по-прежнему будет содержать предыдущее правильное значение (123) - а нужно, чтобы оно при этом сбросилось в null (т.к. в реальности пользователь, как обычно, не обращает внимания на эти сообщения валидации, жмакает на кнопку, и возмущается, что команда отработала с значением, которое он уже вводил). Пробовал экспериментировать с ValidationStep (по умолчанию оно равно RawProposedValue, т.е. правило отрабатывает до конвертера) - получилось не то, что хотелось: при ValidationStep=CommitedValue или UpdatedValue сначала отрабатывает IValueConverter.ConvertBack, постит null-значение в source, потом отрабатывает IValueConverter.Convert, и target апдейтится значением пустой строки, и только после этого отрабатывает ValidationRule, в который приходит пустая строка (а это значение считается валидным - оно нужно для сброса source в null). В результате невалидный текст просто вообще не набирается (что, конечно, хорошо, но чисто ради научного интереса хотелось бы, чтобы он набирался, и программа писала, что Input string was not in a correct format). Как сделать задуманное? ... |
|||
:
Нравится:
Не нравится:
|
|||
16.02.2019, 13:58 |
|
ValidationRule+IValueConverter: сброс source в null при ошибке+отображение ошибки - как?
|
|||
---|---|---|---|
#18+
WinterGraveyard, сразу оговариваюсь - я не спец.., токо начинаю. Но из того что пришло в голову - Вам валидация не нужна. Смысл валидации, именно в то чтьобы не пропускать не корректные данные. А вывод сообщения о некорректности - это визуальная "красивость". Если Вам не нужна валидация, а нужно просто известить пользователя о некорректном значении, то введите вывод извещения или в обработчик TextChanged, или в сеттер свойство VM? к которому привязан Text. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.02.2019, 20:05 |
|
ValidationRule+IValueConverter: сброс source в null при ошибке+отображение ошибки - как?
|
|||
---|---|---|---|
#18+
WinterGraveyardКак сделать задуманное? В озвученной постановке - никак, т.к. налицо взаимоисключающие требования: если ввод неволиден, то источник нужно сбросить в null, а null, как написано выше, валиден как с т.з. типа данных, так и с т.з бизнес-логики (логики валидатора): сброс источника в валидное значение будет протранслирован в target, сработает валидация по валидному значению, и ошибка пропадет (контрол Validation.ErrorTemplate скроется). Что здесь можно сделать: 1. Слушать событие валидации Validation.Error. Не очень удобно - code-behind не всегда доступен, и скрещивать его с вьюмоделью тоже не особенно удобно. Можно использовать паттерн event to command (attached command behavior, Interaction.Triggers из System.Windows.Interactivity), чтобы оповещать модель о невалидном вводе, и вручную синхронизировать сообщения о невалидном вводе, и состояние свойств. Если таких наблюдаемых свойств будет несколько, получится не особенно изящно. 2. Оповещать модель о невалидном вводе прямо из ValidationRule - соответственно, ValidationRule должен иметь ссылку на вьюмодель. Можно её предоставлять с помощь синглтона, сервис-локатора, можно у ValidationRule задать public-свойство на чтение/запись, и в него из xaml-разметки передавать как StaticResource ссылку на вьюмодель, если вьюмодель инициализурется в xaml. Дальше по этой ссылке делать, что нужно - выставлять признаки некорректного ввода, обнулять backing fields свойств (без возбуждения PropertyChanged), итд. Минусы всё те же, что и выше. 3. Держать для свойства 2 поля: одно - текстовое, используемое в биндинге контрола, и валидируемое на шаге CommitedValue. Второе - только для чтения, вычисляемое на лету по содержимому первого свойства. В этом случае при невалидном значении первого свойства (которое будет сохранено в VM, т.к. шаг валидации CommitedValue), второе свойство может вернуть null (по результату парсинга значения первого свойства), и при этом будет отображаться контрол Validation.ErrorTemplate, т.к. валидация отработает с ValidationResult.IsValid = false: Код: xml 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33.
Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65.
Eld HaspСмысл валидации, именно в то чтьобы не пропускать не корректные данные. А вывод сообщения о некорректности - это визуальная "красивость". Ну неправильно же. ValidationRule для ValidationStep=CommitedValue и UpdatedValue отрабатывает тогда, когда валидируемое значение уже передано в источник. Это заложено в дизайн системы валидации. И ТС об этом в курсе, т.к. экспериментировал с этим. Ну, и насчет красивости я бы поспорил. При разборе полетов [якобы] некорректной работы приложения, одним из аргументов обвинения может стать отсутствие нотификации о некорректном вводе. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.02.2019, 08:21 |
|
|
start [/forum/topic.php?fid=21&fpage=4&tid=1440351]: |
0ms |
get settings: |
9ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
134ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
40ms |
get tp. blocked users: |
1ms |
others: | 13ms |
total: | 233ms |
0 / 0 |