diff --git a/src/Avalonia.Base/PropertyStore/LocalValueEntry.cs b/src/Avalonia.Base/PropertyStore/LocalValueEntry.cs new file mode 100644 index 0000000000..416185df05 --- /dev/null +++ b/src/Avalonia.Base/PropertyStore/LocalValueEntry.cs @@ -0,0 +1,19 @@ +using Avalonia.Data; + +#nullable enable + +namespace Avalonia.PropertyStore +{ + internal class LocalValueEntry : IValue + { + public LocalValueEntry(T value) => Value = value; + public Optional Value { get; set; } + public BindingPriority ValuePriority => BindingPriority.LocalValue; + Optional IValue.Value => Value.ToObject(); + + public ConstantValueEntry ToConstantValueEntry(StyledPropertyBase property) + { + return new ConstantValueEntry(property, Value.Value, BindingPriority.LocalValue); + } + } +} diff --git a/src/Avalonia.Base/ValueStore.cs b/src/Avalonia.Base/ValueStore.cs index c3309bf52c..ddcf7ee9c1 100644 --- a/src/Avalonia.Base/ValueStore.cs +++ b/src/Avalonia.Base/ValueStore.cs @@ -41,10 +41,6 @@ namespace Avalonia { return v.Value.HasValue; } - else - { - return true; - } } return false; @@ -62,11 +58,6 @@ namespace Avalonia return true; } } - else - { - value = (T)slot; - return true; - } } value = default!; @@ -81,7 +72,7 @@ namespace Avalonia } else if (priority == BindingPriority.LocalValue) { - _values.AddValue(property, (object)value!); + _values.AddValue(property, new LocalValueEntry(value)); _sink.ValueChanged(property, priority, default, value); } else @@ -174,18 +165,25 @@ namespace Avalonia { p.SetValue(value, priority); } - else if (priority == BindingPriority.LocalValue) + else if (slot is LocalValueEntry l) { - var old = (T)slot; - _values.SetValue(property, (object)value!); - _sink.ValueChanged(property, priority, old, value); + if (priority == BindingPriority.LocalValue) + { + var old = l.Value; + l.Value = value; + _sink.ValueChanged(property, priority, old, value); + } + else + { + var existing = l.ToConstantValueEntry(property); + var priorityValue = new PriorityValue(_owner, property, this, existing); + priorityValue.SetValue(value, priority); + _values.SetValue(property, priorityValue); + } } else { - var existing = new ConstantValueEntry(property, (T)slot, BindingPriority.LocalValue); - var priorityValue = new PriorityValue(_owner, property, this, existing); - priorityValue.SetValue(value, priority); - _values.SetValue(property, priorityValue); + throw new NotSupportedException("Unrecognised value store slot type."); } } @@ -205,11 +203,15 @@ namespace Avalonia { priorityValue = p; } - else + else if (slot is LocalValueEntry l) { - var existing = new ConstantValueEntry(property, (T)slot, BindingPriority.LocalValue); + var existing = l.ToConstantValueEntry(property); priorityValue = new PriorityValue(_owner, property, this, existing); } + else + { + throw new NotSupportedException("Unrecognised value store slot type."); + } var binding = priorityValue.AddBinding(source, priority); _values.SetValue(property, priorityValue);