Browse Source

Fix TextBox validation error persisting when reverting to same valid value (#20780)

* Fix TextBox validation error persisting when reverting to same valid value

When a TwoWay binding with validation had an error and the user set the
target back to the same value that was last successfully written to the
source, WriteTargetValueToSource() would bail out early because the
target value matched LeafNode.Value. This prevented WriteValueToSource()
from being called, so the validation error was never cleared.

Add an ErrorType check to the condition in WriteTargetValueToSource() so
that the write-through still happens when there is a pending validation
error, matching the pattern already used in WriteValueToSource() at
line 310.

Fixes #20534

https://claude.ai/code/session_01LTinLuE1bsNKaLPuDSNuuw

* Add test for validation error clearing when reverting to same valid value

Reproduces the scenario from #20534 where a TwoWay binding with a
setter that throws on invalid values fails to clear the validation error
when the target is set back to the same value that was last successfully
written to the source.

https://claude.ai/code/session_01LTinLuE1bsNKaLPuDSNuuw

* Remove redundant checks in WriteTargetValueToSource()
pull/20804/head
Evan 3 weeks ago
committed by GitHub
parent
commit
c62e1dffff
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 7
      src/Avalonia.Base/Data/Core/BindingExpression.cs
  2. 36
      tests/Avalonia.Base.UnitTests/Data/Core/BindingExpressionTests.DataValidation.cs

7
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));
}
}

36
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()
{

Loading…
Cancel
Save