Browse Source

Merge pull request #11501 from AvaloniaUI/fixes/11484-coercevalue-called-multiple-times

Only call coerce callback a single time.
pull/11506/head
Max Katz 3 years ago
committed by GitHub
parent
commit
7c1122042e
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      src/Avalonia.Base/PropertyStore/EffectiveValue`1.cs
  2. 27
      tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Coercion.cs

5
src/Avalonia.Base/PropertyStore/EffectiveValue`1.cs

@ -208,7 +208,7 @@ namespace Avalonia.PropertyStore
IsOverridenCurrentValue = isOverriddenCurrentValue;
IsCoercedDefaultValue = isCoercedDefaultValue;
if (_uncommon?._coerce is { } coerce)
if (!isCoercedDefaultValue && _uncommon?._coerce is { } coerce)
v = coerce(owner.Owner, value);
if (priority <= Priority)
@ -262,7 +262,8 @@ namespace Avalonia.PropertyStore
if (_uncommon?._coerce is { } coerce)
{
v = coerce(owner.Owner, value);
bv = coerce(owner.Owner, baseValue);
if (priority != basePriority)
bv = coerce(owner.Owner, baseValue);
}
if (!EqualityComparer<T>.Default.Equals(Value, v))

27
tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Coercion.cs

@ -124,6 +124,19 @@ namespace Avalonia.Base.UnitTests
Assert.Equal(2, target.CoreChanges.Count);
}
[Fact]
public void CoerceValue_Calls_Coerce_Callback_Only_Once()
{
var target = new Class1 { Foo = 99 };
target.MaxFoo = 50;
target.CoerceFooInvocations.Clear();
target.CoerceValue(Class1.FooProperty);
Assert.Equal(new[] { 99 }, target.CoerceFooInvocations);
}
[Fact]
public void Coerced_Value_Can_Be_Restored_If_Limit_Changed()
{
@ -218,6 +231,18 @@ namespace Avalonia.Base.UnitTests
Assert.Equal(1, raised);
}
[Fact]
public void Default_Value_Is_Coerced_Only_Once()
{
var target = new Class1();
target.MinFoo = 20;
target.CoerceFooInvocations.Clear();
target.CoerceValue(Class1.FooProperty);
Assert.Equal(new[] { 11 }, target.CoerceFooInvocations);
}
[Fact]
public void ClearValue_Respects_Coerced_Default_Value()
{
@ -338,10 +363,12 @@ namespace Avalonia.Base.UnitTests
public int MinFoo { get; set; } = 0;
public int MaxFoo { get; set; } = 100;
public List<int> CoerceFooInvocations { get; } = new();
public List<AvaloniaPropertyChangedEventArgs> CoreChanges { get; } = new();
public static int CoerceFoo(AvaloniaObject instance, int value)
{
(instance as Class1)?.CoerceFooInvocations.Add(value);
return instance is Class1 o ?
Math.Clamp(value, o.MinFoo, o.MaxFoo) :
Math.Clamp(value, 0, 100);

Loading…
Cancel
Save