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/scripts/ReplaceNugetCache.sh b/scripts/ReplaceNugetCache.sh
index 4cc11edd60..e1c0487d60 100755
--- a/scripts/ReplaceNugetCache.sh
+++ b/scripts/ReplaceNugetCache.sh
@@ -2,7 +2,6 @@
cp ../samples/ControlCatalog.NetCore/bin/Debug/netcoreapp2.0/Avalonia**.dll ~/.nuget/packages/avalonia/$1/lib/netcoreapp2.0/
cp ../samples/ControlCatalog.NetCore/bin/Debug/netcoreapp2.0/Avalonia**.dll ~/.nuget/packages/avalonia/$1/lib/netstandard2.0/
- cp ../samples/ControlCatalog.NetCore/bin/Debug/netcoreapp2.0/Avalonia**.dll ~/.nuget/packages/avalonia.gtk3/$1/lib/netstandard2.0/
cp ../samples/ControlCatalog.NetCore/bin/Debug/netcoreapp2.0/Avalonia**.dll ~/.nuget/packages/avalonia.skia/$1/lib/netstandard2.0/
cp ../samples/ControlCatalog.NetCore/bin/Debug/netcoreapp2.0/Avalonia**.dll ~/.nuget/packages/avalonia.native/$1/lib/netstandard2.0/
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/BoxedValue.cs b/src/Avalonia.Base/BoxedValue.cs
new file mode 100644
index 0000000000..5fc515f299
--- /dev/null
+++ b/src/Avalonia.Base/BoxedValue.cs
@@ -0,0 +1,28 @@
+// Copyright (c) The Avalonia Project. All rights reserved.
+// Licensed under the MIT license. See licence.md file in the project root for full license information.
+
+namespace Avalonia
+{
+ ///
+ /// Represents boxed value of type .
+ ///
+ /// Type of stored value.
+ internal readonly struct BoxedValue
+ {
+ public BoxedValue(T value)
+ {
+ Boxed = value;
+ Typed = value;
+ }
+
+ ///
+ /// Boxed value.
+ ///
+ public object Boxed { get; }
+
+ ///
+ /// Typed value.
+ ///
+ public T Typed { get; }
+ }
+}
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