Browse Source

Merge pull request #10348 from AvaloniaUI/fixes/10255-animation-snaps-back

Two ValueStore fixes.
pull/10358/head
Max Katz 4 years ago
committed by GitHub
parent
commit
b6c56ee64e
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      src/Avalonia.Base/PropertyStore/EffectiveValue`1.cs
  2. 18
      src/Avalonia.Base/PropertyStore/ValueStore.cs
  3. 2
      src/Avalonia.Base/StyledProperty.cs
  4. 16
      tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Binding.cs
  5. 21
      tests/Avalonia.Base.UnitTests/PropertyStore/ValueStoreTests_Inheritance.cs

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

@ -19,13 +19,16 @@ namespace Avalonia.PropertyStore
private T? _baseValue;
private UncommonFields? _uncommon;
public EffectiveValue(AvaloniaObject owner, StyledProperty<T> property)
public EffectiveValue(
AvaloniaObject owner,
StyledProperty<T> property,
EffectiveValue<T>? inherited)
{
Priority = BindingPriority.Unset;
BasePriority = BindingPriority.Unset;
_metadata = property.GetMetadata(owner.GetType());
var value = _metadata.DefaultValue;
var value = inherited is null ? _metadata.DefaultValue : inherited.Value;
if (property.HasCoercion && _metadata.CoerceValue is { } coerce)
{

18
src/Avalonia.Base/PropertyStore/ValueStore.cs

@ -184,7 +184,7 @@ namespace Avalonia.PropertyStore
}
else
{
var effectiveValue = new EffectiveValue<T>(Owner, property);
var effectiveValue = CreateEffectiveValue(property);
AddEffectiveValue(property, effectiveValue);
effectiveValue.SetAndRaise(this, result, priority);
}
@ -200,7 +200,7 @@ namespace Avalonia.PropertyStore
}
else
{
var effectiveValue = new EffectiveValue<T>(Owner, property);
var effectiveValue = CreateEffectiveValue(property);
AddEffectiveValue(property, effectiveValue);
effectiveValue.SetLocalValueAndRaise(this, property, value);
}
@ -217,7 +217,7 @@ namespace Avalonia.PropertyStore
}
else
{
var effectiveValue = new EffectiveValue<T>(Owner, property);
var effectiveValue = CreateEffectiveValue(property);
AddEffectiveValue(property, effectiveValue);
effectiveValue.SetCurrentValueAndRaise(this, property, value);
}
@ -287,6 +287,16 @@ namespace Avalonia.PropertyStore
return false;
}
public EffectiveValue<T> CreateEffectiveValue<T>(StyledProperty<T> property)
{
EffectiveValue<T>? inherited = null;
if (property.Inherits && TryGetInheritedValue(property, out var v))
inherited = (EffectiveValue<T>)v;
return new EffectiveValue<T>(Owner, property, inherited);
}
public void SetInheritanceParent(AvaloniaObject? newParent)
{
var values = AvaloniaPropertyDictionaryPool<OldNewValue>.Get();
@ -799,7 +809,7 @@ namespace Avalonia.PropertyStore
// - The value is a non-animation value and its priority is higher than the current
// effective value's base priority
var isRelevantPriority = current is null ||
priority < current.Priority ||
(priority < current.Priority && priority < current.BasePriority) ||
(priority > BindingPriority.Animation && priority < current.BasePriority);
if (foundEntry && isRelevantPriority && entry!.HasValue)

2
src/Avalonia.Base/StyledProperty.cs

@ -171,7 +171,7 @@ namespace Avalonia
internal override EffectiveValue CreateEffectiveValue(AvaloniaObject o)
{
return new EffectiveValue<TValue>(o, this);
return o.GetValueStore().CreateEffectiveValue(this);
}
/// <inheritdoc/>

16
tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Binding.cs

@ -167,6 +167,22 @@ namespace Avalonia.Base.UnitTests
Assert.Equal("foo", target.GetValue(property));
}
[Fact]
public void Completing_Animation_Binding_Reverts_To_Set_LocalValue_With_Style_Value()
{
var target = new Class1();
var source = new Subject<BindingValue<string>>();
var property = Class1.FooProperty;
target.SetValue(property, "style", BindingPriority.Style);
target.SetValue(property, "foo");
target.Bind(property, source, BindingPriority.Animation);
source.OnNext("bar");
source.OnCompleted();
Assert.Equal("foo", target.GetValue(property));
}
[Fact]
public void Completing_LocalValue_Binding_Raises_PropertyChanged()
{

21
tests/Avalonia.Base.UnitTests/PropertyStore/ValueStoreTests_Inheritance.cs

@ -97,6 +97,27 @@ namespace Avalonia.Base.UnitTests.PropertyStore
Assert.Same(parentStore, grandchild.GetValueStore().InheritanceAncestor);
}
[Fact]
public void Child_Notifies_About_Setting_Back_To_Default_Value()
{
var parent = new Class1();
var child = new Class1();
parent.Foo = "changed";
child.Parent = parent;
bool raised = false;
child.PropertyChanged += (_, args) =>
{
raised = args.Property == Class1.FooProperty && args.GetNewValue<string>() == "foodefault";
};
Assert.Equal("changed", child.Foo); // inherited from parent.
child.Foo = "foodefault"; // reset back to default.
Assert.True(raised); // expect event to be raised, as actual value was changed.
}
[Fact]
public void Adding_Child_Sets_InheritanceAncestor()
{

Loading…
Cancel
Save