|
|
@@ -1,4 +1,5 @@
|
|
|
using System;
|
|
|
+using System.Collections.Generic;
|
|
|
using System.ComponentModel;
|
|
|
using System.Reflection;
|
|
|
using Avalonia.Utilities;
|
|
|
@@ -11,8 +12,11 @@ namespace Avalonia.Data.Core.Plugins
|
|
|
/// </summary>
|
|
|
public class InpcPropertyAccessorPlugin : IPropertyAccessorPlugin
|
|
|
{
|
|
|
+ private readonly Dictionary<(Type, string), PropertyInfo> _propertyLookup =
|
|
|
+ new Dictionary<(Type, string), PropertyInfo>();
|
|
|
+
|
|
|
/// <inheritdoc/>
|
|
|
- public bool Match(object obj, string propertyName) => GetPropertyWithName(obj.GetType(), propertyName) != null;
|
|
|
+ public bool Match(object obj, string propertyName) => GetFirstPropertyWithName(obj.GetType(), propertyName) != null;
|
|
|
|
|
|
/// <summary>
|
|
|
/// Starts monitoring the value of a property on an object.
|
|
|
@@ -30,7 +34,7 @@ namespace Avalonia.Data.Core.Plugins
|
|
|
|
|
|
reference.TryGetTarget(out object instance);
|
|
|
|
|
|
- var p = GetPropertyWithName(instance.GetType(), propertyName);
|
|
|
+ var p = GetFirstPropertyWithName(instance.GetType(), propertyName);
|
|
|
|
|
|
if (p != null)
|
|
|
{
|
|
|
@@ -44,12 +48,40 @@ namespace Avalonia.Data.Core.Plugins
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private static PropertyInfo GetPropertyWithName(Type type, string propertyName)
|
|
|
+ private PropertyInfo GetFirstPropertyWithName(Type type, string propertyName)
|
|
|
{
|
|
|
- const BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Public |
|
|
|
- BindingFlags.Static | BindingFlags.Instance;
|
|
|
+ var key = (type, propertyName);
|
|
|
+
|
|
|
+ if (!_propertyLookup.TryGetValue(key, out PropertyInfo propertyInfo))
|
|
|
+ {
|
|
|
+ propertyInfo = TryFindAndCacheProperty(type, propertyName);
|
|
|
+ }
|
|
|
+
|
|
|
+ return propertyInfo;
|
|
|
+ }
|
|
|
+
|
|
|
+ private PropertyInfo TryFindAndCacheProperty(Type type, string propertyName)
|
|
|
+ {
|
|
|
+ PropertyInfo found = null;
|
|
|
+
|
|
|
+ const BindingFlags bindingFlags =
|
|
|
+ BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance;
|
|
|
+
|
|
|
+ var properties = type.GetProperties(bindingFlags);
|
|
|
+
|
|
|
+ foreach (PropertyInfo propertyInfo in properties)
|
|
|
+ {
|
|
|
+ if (propertyInfo.Name == propertyName)
|
|
|
+ {
|
|
|
+ found = propertyInfo;
|
|
|
+
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ _propertyLookup.Add((type, propertyName), found);
|
|
|
|
|
|
- return type.GetProperty(propertyName, bindingFlags);
|
|
|
+ return found;
|
|
|
}
|
|
|
|
|
|
private class Accessor : PropertyAccessorBase, IWeakSubscriber<PropertyChangedEventArgs>
|