|
|
|
@ -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> |
|
|
|
|