diff --git a/src/Avalonia.Base/AvaloniaObject.cs b/src/Avalonia.Base/AvaloniaObject.cs
index 7e8d733f1b..2a19f40ecb 100644
--- a/src/Avalonia.Base/AvaloniaObject.cs
+++ b/src/Avalonia.Base/AvaloniaObject.cs
@@ -22,27 +22,10 @@ namespace Avalonia
///
public class AvaloniaObject : IAvaloniaObject, IAvaloniaObjectDebug, INotifyPropertyChanged
{
- ///
- /// The parent object that inherited values are inherited from.
- ///
private IAvaloniaObject _inheritanceParent;
-
- ///
- /// Maintains a list of direct property binding subscriptions so that the binding source
- /// doesn't get collected.
- ///
private List _directBindings;
-
- ///
- /// Event handler for implementation.
- ///
private PropertyChangedEventHandler _inpcChanged;
-
- ///
- /// Event handler for implementation.
- ///
private EventHandler _propertyChanged;
-
private ValueStore _values;
private ValueStore Values => _values ?? (_values = new ValueStore(this));
@@ -52,32 +35,7 @@ namespace Avalonia
public AvaloniaObject()
{
VerifyAccess();
-
- void Notify(AvaloniaProperty property)
- {
- object value = property.IsDirect ?
- ((IDirectPropertyAccessor)property).GetValue(this) :
- ((IStyledPropertyAccessor)property).GetDefaultValue(GetType());
-
- var e = new AvaloniaPropertyChangedEventArgs(
- this,
- property,
- AvaloniaProperty.UnsetValue,
- value,
- BindingPriority.Unset);
-
- property.NotifyInitialized(e);
- }
-
- foreach (var property in AvaloniaPropertyRegistry.Instance.GetRegistered(this))
- {
- Notify(property);
- }
-
- foreach (var property in AvaloniaPropertyRegistry.Instance.GetRegisteredAttached(this.GetType()))
- {
- Notify(property);
- }
+ AvaloniaPropertyRegistry.Instance.NotifyInitialized(this);
}
///
@@ -628,7 +586,7 @@ namespace Avalonia
///
/// The property.
/// The default value.
- internal object GetDefaultValue(AvaloniaProperty property)
+ private object GetDefaultValue(AvaloniaProperty property)
{
if (property.Inherits && InheritanceParent is AvaloniaObject aobj)
return aobj.GetValue(property);
diff --git a/src/Avalonia.Base/AvaloniaPropertyRegistry.cs b/src/Avalonia.Base/AvaloniaPropertyRegistry.cs
index 5fcdf76c0f..037e0dd72e 100644
--- a/src/Avalonia.Base/AvaloniaPropertyRegistry.cs
+++ b/src/Avalonia.Base/AvaloniaPropertyRegistry.cs
@@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
+using Avalonia.Data;
namespace Avalonia
{
@@ -23,6 +24,8 @@ namespace Avalonia
new Dictionary>();
private readonly Dictionary> _attachedCache =
new Dictionary>();
+ private readonly Dictionary>> _initializedCache =
+ new Dictionary>>();
///
/// Gets the instance
@@ -226,6 +229,7 @@ namespace Avalonia
}
_registeredCache.Clear();
+ _initializedCache.Clear();
}
///
@@ -261,6 +265,57 @@ namespace Avalonia
}
_attachedCache.Clear();
+ _initializedCache.Clear();
+ }
+
+ internal void NotifyInitialized(AvaloniaObject o)
+ {
+ Contract.Requires(o != null);
+
+ var type = o.GetType();
+
+ void Notify(AvaloniaProperty property, object value)
+ {
+ var e = new AvaloniaPropertyChangedEventArgs(
+ o,
+ property,
+ AvaloniaProperty.UnsetValue,
+ value,
+ BindingPriority.Unset);
+
+ property.NotifyInitialized(e);
+ }
+
+ if (!_initializedCache.TryGetValue(type, out var items))
+ {
+ var build = new Dictionary();
+
+ foreach (var property in GetRegistered(type))
+ {
+ var value = !property.IsDirect ?
+ ((IStyledPropertyAccessor)property).GetDefaultValue(type) :
+ null;
+ build.Add(property, value);
+ }
+
+ foreach (var property in GetRegisteredAttached(type))
+ {
+ if (!build.ContainsKey(property))
+ {
+ var value = ((IStyledPropertyAccessor)property).GetDefaultValue(type);
+ build.Add(property, value);
+ }
+ }
+
+ items = build.ToList();
+ _initializedCache.Add(type, items);
+ }
+
+ foreach (var i in items)
+ {
+ var value = i.Key.IsDirect ? o.GetValue(i.Key) : i.Value;
+ Notify(i.Key, value);
+ }
}
}
}