|
Привязка от UserControl к ViewModel
|
|||
---|---|---|---|
#18+
Столкнулся с непонятным (для меня) поведением привязки Простая ViewModel Код: c# 1. 2. 3. 4. 5. 6. 7.
Простой UC с одним DP-свойством Код: xml 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.
Код: 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.
View использующая указанные VM и UC Код: xml 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23.
В UC идёт ограничение присваиваемого Value значения по минимальному значению 5. Если присвоить значение меньше пяти, то в UC и ViewModel оказываются разные значения. В UC установленное минимальное значение, в ViewModel - то значение которое пытались установить в UC. Вопрос - так и должно быть или я где-то туплю? ... |
|||
:
Нравится:
Не нравится:
|
|||
11.07.2019, 12:59 |
|
Привязка от UserControl к ViewModel
|
|||
---|---|---|---|
#18+
Забыл CB приложить Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
... |
|||
:
Нравится:
Не нравится:
|
|||
11.07.2019, 14:46 |
|
Привязка от UserControl к ViewModel
|
|||
---|---|---|---|
#18+
Eld HaspВопрос - так и должно быть или я где-то туплю? Не то что бы так должно быть (по-хорошему), но оно действительно так: CoerceValueCallback удерживает только значение DependencyProperty, на значения, передаваемые через биндинг, он не влияет. Обычно в таком случае, если удерживаемое значение не равно переданному, дополнительно делают что-то типа Код: c# 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
11.07.2019, 17:09 |
|
Привязка от UserControl к ViewModel
|
|||
---|---|---|---|
#18+
Сон Веры ПавловныEld HaspВопрос - так и должно быть или я где-то туплю? Не то что бы так должно быть (по-хорошему), но оно действительно так: CoerceValueCallback удерживает только значение DependencyProperty, на значения, передаваемые через биндинг, он не влияет. Обычно в таком случае, если удерживаемое значение не равно переданному, дополнительно делают что-то типа Код: c# 1.
Это пробовал. Куда не вставь UpdateSource() тоже всё криво работает. Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21.
Помогает только вариант со вторичным присваиванием значения. Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
Но такой код мне кажется "плохо попахивает". Или он норм? ... |
|||
:
Нравится:
Не нравится:
|
|||
11.07.2019, 18:21 |
|
Привязка от UserControl к ViewModel
|
|||
---|---|---|---|
#18+
Eld HaspНо такой код мне кажется "плохо попахивает". Или он норм? Других работающих вариантов всё равно нет. Проблема старая, и на неё натыкались многие - вот, например . ... |
|||
:
Нравится:
Не нравится:
|
|||
12.07.2019, 11:32 |
|
Привязка от UserControl к ViewModel
|
|||
---|---|---|---|
#18+
может потому, что это не валидация? :) CoerceValueCallback служит для создания ограничений допустимых значений свойства. Грубо говоря. если у вас есть 3 свойства Min, Max, Value, то логично, что ограничение Max не может быть меньше Min, а Value должно лежать в заданных рамках. В обратную сторону это не действует, ограничения действуют только в рамках самого свойства зависимости. Если в модели представления задать Max меньше чем Min, в ProgressBar, то значение Max будет просто равно значению Min. Как это работает можно посмотреть на реализации этого элемента управления. То есть, это нужно для создания собственных элементов управления, безотносительно модели представления. Чтоб значения свойств не выходили за допустимые рамки. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.07.2019, 11:49 |
|
Привязка от UserControl к ViewModel
|
|||
---|---|---|---|
#18+
еще для полного понимания стоит почитать про приоритеты значений, чтоб не возникало вопросов, почему я задаю одно значение свойству, а у него совсем другое значение https://docs.microsoft.com/ru-ru/dotnet/framework/wpf/advanced/dependency-property-value-precedence ... |
|||
:
Нравится:
Не нравится:
|
|||
12.07.2019, 11:52 |
|
Привязка от UserControl к ViewModel
|
|||
---|---|---|---|
#18+
Roman Mejtesможет потому, что это не валидация? :) CoerceValueCallback служит для создания ограничений допустимых значений свойства. Грубо говоря. если у вас есть 3 свойства Min, Max, Value, то логично, что ограничение Max не может быть меньше Min, а Value должно лежать в заданных рамках. В обратную сторону это не действует, ограничения действуют только в рамках самого свойства зависимости. Если в модели представления задать Max меньше чем Min, в ProgressBar, то значение Max будет просто равно значению Min. Как это работает можно посмотреть на реализации этого элемента управления. То есть, это нужно для создания собственных элементов управления, безотносительно модели представления. Чтоб значения свойств не выходили за допустимые рамки. Так я и пытаюсь организовать ограничение минимального значения. И делаю именно по примеру от microsoft. Оно всё вроде работает как и надо. Пока я не задал привязку в свойстве. Кроме этой привязки всё работает. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.07.2019, 21:00 |
|
Привязка от UserControl к ViewModel
|
|||
---|---|---|---|
#18+
Roman Mejtesеще для полного понимания стоит почитать про приоритеты значений, чтоб не возникало вопросов, почему я задаю одно значение свойству, а у него совсем другое значение https://docs.microsoft.com/ru-ru/dotnet/framework/wpf/advanced/dependency-property-value-precedence Прочитал, только не понял какое отношение это имеет к обсуждаемой проблеме. На мой взгляд это очевидный баг. В настоящее присвоение значения работает так: SetValue -> Исходящая привязка в свойстве -> coerceValueCallback -> propertyChangedCallback -> Присвоение значения -> Внешние привязки К свойству На мой взгляд " Исходящая привязка в свойстве" должна работать после "Присвоения значения" одновременно с "Внешними привязка" ... |
|||
:
Нравится:
Не нравится:
|
|||
12.07.2019, 21:11 |
|
Привязка от UserControl к ViewModel
|
|||
---|---|---|---|
#18+
Сон Веры ПавловныEld HaspНо такой код мне кажется "плохо попахивает". Или он норм? Других работающих вариантов всё равно нет. Проблема старая, и на неё натыкались многие - вот, например . Спасибо за внимание к теме! Придётся пользоваться костылём. Странно, что от MS нет никакой реакции на столь давно обсуждаемый баг (на мой взгляд). ... |
|||
:
Нравится:
Не нравится:
|
|||
12.07.2019, 21:23 |
|
Привязка от UserControl к ViewModel
|
|||
---|---|---|---|
#18+
Roman Mejtesможет потому, что это не валидация? :) CoerceValueCallback служит для создания ограничений допустимых значений свойства. Грубо говоря. если у вас есть 3 свойства Min, Max, Value, то логично, что ограничение Max не может быть меньше Min, а Value должно лежать в заданных рамках. В обратную сторону это не действует, ограничения действуют только в рамках самого свойства зависимости.С задержкой, но понял вашу мысль. Раз это внутреннее ограничение DP, то и влиять на источник данных она не должна. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.07.2019, 13:42 |
|
Привязка от UserControl к ViewModel
|
|||
---|---|---|---|
#18+
Нашёл разъяснение от MS Advanced Coercion and Callback Scenarios Constraints and Desired Values The CoerceValueCallback callbacks will be used by the property system to coerce a value in accordance to the logic you declare, but a coerced value of a locally set property will still retain a "desired value" internally. If the constraints are based on other property values that may change dynamically during the application lifetime, the coercion constraints are changed dynamically also, and the constrained property can change its value to get as close to the desired value as possible given the new constraints. The value will become the desired value if all constraints are lifted. You can potentially introduce some fairly complicated dependency scenarios if you have multiple properties that are dependent on one another in a circular manner. For instance, in the Min/Max/Current scenario, you could choose to have Minimum and Maximum be user settable. If so, you might need to coerce that Maximum is always greater than Minimum and vice versa. But if that coercion is active, and Maximum coerces to Minimum, it leaves Current in an unsettable state, because it is dependent on both and is constrained to the range between the values, which is zero. Then, if Maximum or Minimum are adjusted, Current will seem to "follow" one of the values, because the desired value of Current is still stored and is attempting to reach the desired value as the constraints are loosened. There is nothing technically wrong with complex dependencies, but they can be a slight performance detriment if they require large numbers of reevaluations, and can also be confusing to users if they affect the UI directly. Be careful with property changed and coerce value callbacks and make sure that the coercion being attempted can be treated as unambiguously as possible, and does not "overconstrain". Using CoerceValue to Cancel Value Changes The property system will treat any CoerceValueCallback that returns the value UnsetValue as a special case. This special case means that the property change that resulted in the CoerceValueCallback being called should be rejected by the property system, and that the property system should instead report whatever previous value the property had. This mechanism can be useful to check that changes to a property that were initiated asynchronously are still valid for the current object state, and suppress the changes if not. Another possible scenario is that you can selectively suppress a value depending on which component of property value determination is responsible for the value being reported. To do this, you can use the DependencyProperty passed in the callback and the property identifier as input for GetValueSource, and then process the ValueSource. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.07.2019, 13:55 |
|
|
start [/forum/topic.php?fid=21&msg=39836490&tid=1440320]: |
0ms |
get settings: |
9ms |
get forum list: |
10ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
27ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
48ms |
get tp. blocked users: |
1ms |
others: | 14ms |
total: | 127ms |
0 / 0 |