|
|
@@ -24,8 +24,8 @@ namespace Avalonia
|
|
|
new Dictionary<Type, List<AvaloniaProperty>>();
|
|
|
private readonly Dictionary<Type, List<AvaloniaProperty>> _attachedCache =
|
|
|
new Dictionary<Type, List<AvaloniaProperty>>();
|
|
|
- private readonly Dictionary<Type, List<KeyValuePair<AvaloniaProperty, object>>> _initializedCache =
|
|
|
- new Dictionary<Type, List<KeyValuePair<AvaloniaProperty, object>>>();
|
|
|
+ private readonly Dictionary<Type, List<PropertyInitializationData>> _initializedCache =
|
|
|
+ new Dictionary<Type, List<PropertyInitializationData>>();
|
|
|
|
|
|
/// <summary>
|
|
|
/// Gets the <see cref="AvaloniaPropertyRegistry"/> instance
|
|
|
@@ -286,35 +286,73 @@ namespace Avalonia
|
|
|
property.NotifyInitialized(e);
|
|
|
}
|
|
|
|
|
|
- if (!_initializedCache.TryGetValue(type, out var items))
|
|
|
+ if (!_initializedCache.TryGetValue(type, out var initializationData))
|
|
|
{
|
|
|
- var build = new Dictionary<AvaloniaProperty, object>();
|
|
|
+ var visited = new HashSet<AvaloniaProperty>();
|
|
|
|
|
|
- foreach (var property in GetRegistered(type))
|
|
|
+ initializationData = new List<PropertyInitializationData>();
|
|
|
+
|
|
|
+ foreach (AvaloniaProperty property in GetRegistered(type))
|
|
|
{
|
|
|
- var value = !property.IsDirect ?
|
|
|
- ((IStyledPropertyAccessor)property).GetDefaultValue(type) :
|
|
|
- null;
|
|
|
- build.Add(property, value);
|
|
|
+ if (property.IsDirect)
|
|
|
+ {
|
|
|
+ initializationData.Add(new PropertyInitializationData(property, (IDirectPropertyAccessor)property));
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ initializationData.Add(new PropertyInitializationData(property, (IStyledPropertyAccessor)property, type));
|
|
|
+ }
|
|
|
+
|
|
|
+ visited.Add(property);
|
|
|
}
|
|
|
|
|
|
- foreach (var property in GetRegisteredAttached(type))
|
|
|
+ foreach (AvaloniaProperty property in GetRegisteredAttached(type))
|
|
|
{
|
|
|
- if (!build.ContainsKey(property))
|
|
|
+ if (!visited.Contains(property))
|
|
|
{
|
|
|
- var value = ((IStyledPropertyAccessor)property).GetDefaultValue(type);
|
|
|
- build.Add(property, value);
|
|
|
+ initializationData.Add(new PropertyInitializationData(property, (IStyledPropertyAccessor)property, type));
|
|
|
+
|
|
|
+ visited.Add(property);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- items = build.ToList();
|
|
|
- _initializedCache.Add(type, items);
|
|
|
+ _initializedCache.Add(type, initializationData);
|
|
|
+ }
|
|
|
+
|
|
|
+ foreach (PropertyInitializationData data in initializationData)
|
|
|
+ {
|
|
|
+ if (!data.Property.HasNotifyInitializedObservers)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ object value = data.IsDirect ? data.DirectAccessor.GetValue(o) : data.Value;
|
|
|
+
|
|
|
+ Notify(data.Property, value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private readonly struct PropertyInitializationData
|
|
|
+ {
|
|
|
+ public AvaloniaProperty Property { get; }
|
|
|
+ public object Value { get; }
|
|
|
+ public bool IsDirect { get; }
|
|
|
+ public IDirectPropertyAccessor DirectAccessor { get; }
|
|
|
+
|
|
|
+ public PropertyInitializationData(AvaloniaProperty property, IDirectPropertyAccessor directAccessor)
|
|
|
+ {
|
|
|
+ Property = property;
|
|
|
+ Value = null;
|
|
|
+ IsDirect = true;
|
|
|
+ DirectAccessor = directAccessor;
|
|
|
}
|
|
|
|
|
|
- foreach (var i in items)
|
|
|
+ public PropertyInitializationData(AvaloniaProperty property, IStyledPropertyAccessor styledAccessor, Type type)
|
|
|
{
|
|
|
- var value = i.Key.IsDirect ? o.GetValue(i.Key) : i.Value;
|
|
|
- Notify(i.Key, value);
|
|
|
+ Property = property;
|
|
|
+ Value = styledAccessor.GetDefaultValue(type);
|
|
|
+ IsDirect = false;
|
|
|
+ DirectAccessor = null;
|
|
|
}
|
|
|
}
|
|
|
}
|