You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is a very old issue that, as I understand it, has existing in WPF from the beginning (almost 20 years!). It came up again recently so pulling it out into a separate issue here.
Here was a nice summary by @tomenscape:
If the recipient object changes the value to something other than the one that was set, a property changed event is raised and the binding can update the sender object. But if the recipient object instead ignores the new value (as is the case here), then no event is raised and no action is taken.
Basically when a cancel happens in the coerce method the property value is reverted back to its original value. This means the value hasn't actually changed and no change notification happens -- seems to make sense. However, if two controls are two-way bound this actually causes a desync. Because the sender will still change its state.
My simple understanding (without looking at any control flow) is:
Sender changes value (say true -> false)
Receiver coerces value
Coercion raises cancel events and external code cancels the change (value switch false -> true)
The value 'true' is set to the control... but this is the same as it was before. Therefore no change notification and updates.
The sender still has a false value instead of true because it never got a change notification because the value didn't actually change.
So an additional check is needed to see if coercion changes the value to a value other than what went into the coerce method. If so, and there is a two-way binding, it needs to notify the sender of a change even when the value set to the control is actually the same.
(ViewModel Example)
This same issue can be seen if a ViewModel internally reverts/rejects a property change immediately in the setter (or some other place). In that situation it's common to see it fixed by forcefully raising a PropertyChanged notification.
Expected behavior
Two-way bound values should never descyn like this. This case needs to be handled.
It should be supported for receivers to cancel/revert value changes. This is especially true with coercion which definitely can change a value back to original. But also in view models as well.
Forcefully raising a property changed notification to re-evaluate bindings seems like a useful API to support externally as well. It helps a lot to work-around any binding issues encountered. Of course the first solution is to fix binding edge cases like this.
Screenshots
None
Desktop (please complete the following information):
OS: All (N/A)
Version Avalonia 11.0 preview 4
Additional context
This was discussed most in #9979 (comment) and broken out as a separate issue.
The text was updated successfully, but these errors were encountered:
I have been getting bitten by this with a ComboBox setting its SelectedItem to null when the VM wouldn't accept it. A complicated mess of filters, etc. A way to manually force a PropertyChanged notification would have been nice, as that's what I thought I was doing already and would have handled the situation. Except for ReactiveUI being too clever and refusing to raise it.
Describe the bug
This is a very old issue that, as I understand it, has existing in WPF from the beginning (almost 20 years!). It came up again recently so pulling it out into a separate issue here.
Here was a nice summary by @tomenscape:
To Reproduce
Steps to reproduce the behavior:
(Coercion Example)
Basically when a cancel happens in the coerce method the property value is reverted back to its original value. This means the value hasn't actually changed and no change notification happens -- seems to make sense. However, if two controls are two-way bound this actually causes a desync. Because the sender will still change its state.
My simple understanding (without looking at any control flow) is:
So an additional check is needed to see if coercion changes the value to a value other than what went into the coerce method. If so, and there is a two-way binding, it needs to notify the sender of a change even when the value set to the control is actually the same.
(ViewModel Example)
This same issue can be seen if a ViewModel internally reverts/rejects a property change immediately in the setter (or some other place). In that situation it's common to see it fixed by forcefully raising a PropertyChanged notification.
Expected behavior
Forcefully raising a property changed notification to re-evaluate bindings seems like a useful API to support externally as well. It helps a lot to work-around any binding issues encountered. Of course the first solution is to fix binding edge cases like this.
Screenshots
None
Desktop (please complete the following information):
Additional context
This was discussed most in #9979 (comment) and broken out as a separate issue.
The text was updated successfully, but these errors were encountered: