diff --git a/build/SharedVersion.props b/build/SharedVersion.props
index 76abcf6912..44d5c239ef 100644
--- a/build/SharedVersion.props
+++ b/build/SharedVersion.props
@@ -4,11 +4,16 @@
Avalonia
0.8.999
Copyright 2019 © The AvaloniaUI Project
- https://github.com/AvaloniaUI/Avalonia/blob/master/licence.md
- https://github.com/AvaloniaUI/Avalonia/
+ https://avaloniaui.net
https://github.com/AvaloniaUI/Avalonia/
true
CS1591
latest
+ MIT
+ https://avatars2.githubusercontent.com/u/14075148?s=200
+ Avalonia is a WPF/UWP-inspired cross-platform XAML-based UI framework providing a flexible styling system and supporting a wide range of Operating Systems such as Windows (.NET Framework, .NET Core), Linux (via Xorg), MacOS and with experimental support for Android and iOS.
+ avalonia;avaloniaui;mvvm;rx;reactive extensions;android;ios;mac;forms;wpf;net;netstandard;net461;uwp;xamarin
+ https://github.com/AvaloniaUI/Avalonia/releases
+ git
diff --git a/src/Avalonia.Animation/Animatable.cs b/src/Avalonia.Animation/Animatable.cs
index 3a3d00b94a..2c321b8b28 100644
--- a/src/Avalonia.Animation/Animatable.cs
+++ b/src/Avalonia.Animation/Animatable.cs
@@ -45,16 +45,17 @@ namespace Avalonia.Animation
{
get
{
- if (_transitions == null)
+ if (_transitions is null)
_transitions = new Transitions();
- if (_previousTransitions == null)
+ if (_previousTransitions is null)
_previousTransitions = new Dictionary();
return _transitions;
}
set
{
+
SetAndRaise(TransitionsProperty, ref _transitions, value);
}
}
@@ -66,18 +67,20 @@ namespace Avalonia.Animation
/// The event args.
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs e)
{
- if (e.Priority != BindingPriority.Animation && Transitions != null && _previousTransitions != null)
- {
- var match = Transitions.FirstOrDefault(x => x.Property == e.Property);
+ if (_transitions is null || _previousTransitions is null || e.Priority == BindingPriority.Animation) return;
- if (match != null)
+ // PERF-SENSITIVE: Called on every property change. Don't use LINQ here (too many allocations).
+ foreach (var transition in Transitions)
+ {
+ if (transition.Property == e.Property)
{
if (_previousTransitions.TryGetValue(e.Property, out var dispose))
dispose.Dispose();
- var instance = match.Apply(this, Clock ?? Avalonia.Animation.Clock.GlobalClock, e.OldValue, e.NewValue);
+ var instance = transition.Apply(this, Clock ?? Avalonia.Animation.Clock.GlobalClock, e.OldValue, e.NewValue);
_previousTransitions[e.Property] = instance;
+ return;
}
}
}
diff --git a/src/Avalonia.Base/AvaloniaObject.cs b/src/Avalonia.Base/AvaloniaObject.cs
index 0e2f0feada..94558c4367 100644
--- a/src/Avalonia.Base/AvaloniaObject.cs
+++ b/src/Avalonia.Base/AvaloniaObject.cs
@@ -208,20 +208,9 @@ namespace Avalonia
{
return ((IDirectPropertyAccessor)GetRegistered(property)).GetValue(this);
}
- else if (_values != null)
- {
- var result = Values.GetValue(property);
-
- if (result == AvaloniaProperty.UnsetValue)
- {
- result = GetDefaultValue(property);
- }
-
- return result;
- }
else
{
- return GetDefaultValue(property);
+ return GetValueOrDefaultUnchecked(property);
}
}
@@ -598,10 +587,46 @@ namespace Avalonia
private object GetDefaultValue(AvaloniaProperty property)
{
if (property.Inherits && InheritanceParent is AvaloniaObject aobj)
- return aobj.GetValue(property);
+ return aobj.GetValueOrDefaultUnchecked(property);
return ((IStyledPropertyAccessor) property).GetDefaultValue(GetType());
}
+ ///
+ /// Gets the value or default value for a property.
+ ///
+ /// The property.
+ /// The default value.
+ private object GetValueOrDefaultUnchecked(AvaloniaProperty property)
+ {
+ var aobj = this;
+ var valuestore = aobj._values;
+ if (valuestore != null)
+ {
+ var result = valuestore.GetValue(property);
+ if (result != AvaloniaProperty.UnsetValue)
+ {
+ return result;
+ }
+ }
+ if (property.Inherits)
+ {
+ while (aobj.InheritanceParent is AvaloniaObject parent)
+ {
+ aobj = parent;
+ valuestore = aobj._values;
+ if (valuestore != null)
+ {
+ var result = valuestore.GetValue(property);
+ if (result != AvaloniaProperty.UnsetValue)
+ {
+ return result;
+ }
+ }
+ }
+ }
+ return ((IStyledPropertyAccessor)property).GetDefaultValue(GetType());
+ }
+
///
/// Sets the value of a direct property.
///
diff --git a/src/Avalonia.Base/PriorityBindingEntry.cs b/src/Avalonia.Base/PriorityBindingEntry.cs
index d4a47306a7..95add0dfac 100644
--- a/src/Avalonia.Base/PriorityBindingEntry.cs
+++ b/src/Avalonia.Base/PriorityBindingEntry.cs
@@ -2,6 +2,7 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
+using System.Runtime.ExceptionServices;
using Avalonia.Data;
using Avalonia.Threading;
@@ -10,9 +11,9 @@ namespace Avalonia
///
/// A registered binding in a .
///
- internal class PriorityBindingEntry : IDisposable
+ internal class PriorityBindingEntry : IDisposable, IObserver