diff --git a/src/Avalonia.Base/Data/Core/BindingExpression.cs b/src/Avalonia.Base/Data/Core/BindingExpression.cs index 00a90f87fe..81a21955c4 100644 --- a/src/Avalonia.Base/Data/Core/BindingExpression.cs +++ b/src/Avalonia.Base/Data/Core/BindingExpression.cs @@ -460,12 +460,9 @@ internal class BindingExpression : UntypedBindingExpressionBase, IDescription, I StopDelayTimer(); if (TryGetTarget(out var target) && - TargetProperty is not null && - target.GetValue(TargetProperty) is var value && - LeafNode is { } leafNode && - !TypeUtilities.IdentityEquals(value, leafNode.Value, TargetType)) + TargetProperty is not null) { - WriteValueToSource(value); + WriteValueToSource(target.GetValue(TargetProperty)); } } diff --git a/tests/Avalonia.Base.UnitTests/Data/Core/BindingExpressionTests.DataValidation.cs b/tests/Avalonia.Base.UnitTests/Data/Core/BindingExpressionTests.DataValidation.cs index 04aa7b8de2..1575bf6ad3 100644 --- a/tests/Avalonia.Base.UnitTests/Data/Core/BindingExpressionTests.DataValidation.cs +++ b/tests/Avalonia.Base.UnitTests/Data/Core/BindingExpressionTests.DataValidation.cs @@ -133,6 +133,42 @@ public partial class BindingExpressionTests GC.KeepAlive(data); } + [Fact] + public void Setter_Exception_Error_Is_Cleared_When_Reverting_To_Same_Valid_Value() + { + // Issue #20534: When a setter throws on an invalid value and the user + // reverts to the same valid value that was last successfully set, the + // validation error should be cleared. + var data = new ExceptionViewModel { MustBePositive = 5 }; + + var target = CreateTargetWithSource( + data, + o => o.MustBePositive, + enableDataValidation: true, + mode: BindingMode.TwoWay); + + // Step 1: Set a valid value. + target.Int = 10; + Assert.Equal(10, data.MustBePositive); + AssertNoError(target, TargetClass.IntProperty); + + // Step 2: Set an invalid value — setter throws, error appears. + target.Int = -5; + Assert.Equal(10, data.MustBePositive); + AssertBindingError( + target, + TargetClass.IntProperty, + new ArgumentOutOfRangeException("value"), + BindingErrorType.DataValidationError); + + // Step 3: Revert to the same valid value (10). The error must clear. + target.Int = 10; + Assert.Equal(10, data.MustBePositive); + AssertNoError(target, TargetClass.IntProperty); + + GC.KeepAlive(data); + } + [Fact] public void Indei_Validation_Does_Not_Subscribe_When_DataValidation_Not_Enabled() {