Browse Source

Merge pull request #10858 from AvaloniaUI/fixes/inherited-property-change

Fix inherited property change notifications.
pull/10861/head
Max Katz 4 years ago
committed by GitHub
parent
commit
afede23e75
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      src/Avalonia.Base/PropertyStore/EffectiveValue`1.cs
  2. 8
      src/Avalonia.Base/PropertyStore/ValueStore.cs
  3. 30
      tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Inheritance.cs

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

@ -140,24 +140,24 @@ namespace Avalonia.PropertyStore
var p = (StyledProperty<T>)property;
BindingPriority priority;
T oldValue;
T newValue;
if (property.Inherits && owner.TryGetInheritedValue(property, out var i))
{
oldValue = ((EffectiveValue<T>)i).Value;
newValue = ((EffectiveValue<T>)i).Value;
priority = BindingPriority.Inherited;
}
else
{
oldValue = _metadata.DefaultValue;
newValue = _metadata.DefaultValue;
priority = BindingPriority.Unset;
}
if (!EqualityComparer<T>.Default.Equals(oldValue, Value))
if (!EqualityComparer<T>.Default.Equals(newValue, Value))
{
owner.Owner.RaisePropertyChanged(p, Value, oldValue, priority, true);
owner.Owner.RaisePropertyChanged(p, Value, newValue, priority, true);
if (property.Inherits)
owner.OnInheritedEffectiveValueDisposed(p, Value);
owner.OnInheritedEffectiveValueDisposed(p, Value, newValue);
}
if (ValueEntry?.GetDataValidationState(out _, out _) ??

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

@ -419,7 +419,9 @@ namespace Avalonia.PropertyStore
ReevaluateEffectiveValue(property, current);
}
else
{
ReevaluateEffectiveValues();
}
}
/// <summary>
@ -481,7 +483,8 @@ namespace Avalonia.PropertyStore
/// </summary>
/// <param name="property">The property whose value changed.</param>
/// <param name="oldValue">The old value of the property.</param>
public void OnInheritedEffectiveValueDisposed<T>(StyledProperty<T> property, T oldValue)
/// <param name="newValue">The new value of the property.</param>
public void OnInheritedEffectiveValueDisposed<T>(StyledProperty<T> property, T oldValue, T newValue)
{
Debug.Assert(property.Inherits);
@ -489,12 +492,11 @@ namespace Avalonia.PropertyStore
if (children is not null)
{
var defaultValue = property.GetDefaultValue(Owner.GetType());
var count = children.Count;
for (var i = 0; i < count; ++i)
{
children[i].GetValueStore().OnAncestorInheritedValueChanged(property, oldValue, defaultValue);
children[i].GetValueStore().OnAncestorInheritedValueChanged(property, oldValue, newValue);
}
}
}

30
tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Inheritance.cs

@ -1,5 +1,10 @@
using System.Collections.Generic;
using Avalonia.Controls;
using Avalonia.Controls.Documents;
using Avalonia.Data;
using Avalonia.Media;
using Avalonia.Styling;
using Avalonia.UnitTests;
using Xunit;
namespace Avalonia.Base.UnitTests
@ -90,6 +95,31 @@ namespace Avalonia.Base.UnitTests
Assert.Equal(1, raised);
}
[Fact]
public void ClearValue_On_Parent_Raises_PropertyChanged_On_Child_With_Inherited_Grandparent_Value()
{
var grandparent = new Class1();
var parent = new Class2 { Parent = grandparent };
var child = new Class2 { Parent = parent };
var raised = 0;
grandparent.SetValue(Class1.BazProperty, "grandparent");
parent.SetValue(Class1.BazProperty, "parent");
child.PropertyChanged += (s, e) =>
{
Assert.Same(child, e.Sender);
Assert.Equal("parent", e.OldValue);
Assert.Equal("grandparent", e.NewValue);
Assert.Equal(BindingPriority.Inherited, e.Priority);
++raised;
};
parent.ClearValue(Class1.BazProperty);
Assert.Equal(1, raised);
}
[Fact]
public void Setting_InheritanceParent_Raises_PropertyChanged_When_Parent_Has_Value_Set()
{

Loading…
Cancel
Save