diff --git a/src/Avalonia.Base/Utilities/WeakObservable.cs b/src/Avalonia.Base/Utilities/WeakObservable.cs index c261cc0520..b1fe78c206 100644 --- a/src/Avalonia.Base/Utilities/WeakObservable.cs +++ b/src/Avalonia.Base/Utilities/WeakObservable.cs @@ -16,12 +16,13 @@ namespace Avalonia.Utilities /// Converts a .NET event conforming to the standard .NET event pattern into an observable /// sequence, subscribing weakly. /// + /// The type of target. /// The type of the event args. /// Object instance that exposes the event to convert. /// Name of the event to convert. /// - public static IObservable> FromEventPattern( - object target, + public static IObservable> FromEventPattern( + TTarget target, string eventName) where TEventArgs : EventArgs { diff --git a/src/Avalonia.Base/Utilities/WeakSubscriptionManager.cs b/src/Avalonia.Base/Utilities/WeakSubscriptionManager.cs index 356be2ba31..1455feb6ff 100644 --- a/src/Avalonia.Base/Utilities/WeakSubscriptionManager.cs +++ b/src/Avalonia.Base/Utilities/WeakSubscriptionManager.cs @@ -21,18 +21,20 @@ namespace Avalonia.Utilities /// The event source. /// The name of the event. /// The subscriber. - public static void Subscribe(object target, string eventName, IWeakSubscriber subscriber) - where T : EventArgs + /// The type of the target. + /// The type of the event args. + public static void Subscribe(TTarget target, string eventName, IWeakSubscriber subscriber) + where TEventArgs : EventArgs { - var dic = SubscriptionTypeStorage.Subscribers.GetOrCreateValue(target); - Subscription sub; + var dic = SubscriptionTypeStorage.Subscribers.GetOrCreateValue(target); + Subscription sub; if (!dic.TryGetValue(eventName, out sub)) { - dic[eventName] = sub = new Subscription(dic, target, eventName); + dic[eventName] = sub = new Subscription(dic, typeof(TTarget), target, eventName); } - sub.Add(new WeakReference>(subscriber)); + sub.Add(new WeakReference>(subscriber)); } /// @@ -84,19 +86,18 @@ namespace Avalonia.Utilities private WeakReference>[] _data = new WeakReference>[16]; private int _count = 0; - public Subscription(SubscriptionDic sdic, object target, string eventName) + public Subscription(SubscriptionDic sdic, Type targetType, object target, string eventName) { _sdic = sdic; _target = target; _eventName = eventName; - var t = target.GetType(); Dictionary evDic; - if (!Accessors.TryGetValue(t, out evDic)) - Accessors[t] = evDic = new Dictionary(); + if (!Accessors.TryGetValue(targetType, out evDic)) + Accessors[targetType] = evDic = new Dictionary(); if (!evDic.TryGetValue(eventName, out _info)) { - var ev = t.GetRuntimeEvents().FirstOrDefault(x => x.Name == eventName); + var ev = targetType.GetRuntimeEvents().FirstOrDefault(x => x.Name == eventName); if (ev == null) { diff --git a/src/Markup/Avalonia.Markup/Data/IndexerNode.cs b/src/Markup/Avalonia.Markup/Data/IndexerNode.cs index 8ab665c4a4..4e2914a148 100644 --- a/src/Markup/Avalonia.Markup/Data/IndexerNode.cs +++ b/src/Markup/Avalonia.Markup/Data/IndexerNode.cs @@ -33,8 +33,8 @@ namespace Avalonia.Markup.Data if (incc != null) { - inputs.Add(WeakObservable.FromEventPattern( - target, + inputs.Add(WeakObservable.FromEventPattern( + incc, nameof(incc.CollectionChanged)) .Where(x => ShouldUpdate(x.Sender, x.EventArgs)) .Select(_ => GetValue(target))); @@ -42,8 +42,8 @@ namespace Avalonia.Markup.Data if (inpc != null) { - inputs.Add(WeakObservable.FromEventPattern( - target, + inputs.Add(WeakObservable.FromEventPattern( + inpc, nameof(inpc.PropertyChanged)) .Where(x => ShouldUpdate(x.Sender, x.EventArgs)) .Select(_ => GetValue(target))); diff --git a/src/Markup/Avalonia.Markup/Data/Plugins/AvaloniaPropertyAccessorPlugin.cs b/src/Markup/Avalonia.Markup/Data/Plugins/AvaloniaPropertyAccessorPlugin.cs index 1d4a9a688e..3f6f15ed5b 100644 --- a/src/Markup/Avalonia.Markup/Data/Plugins/AvaloniaPropertyAccessorPlugin.cs +++ b/src/Markup/Avalonia.Markup/Data/Plugins/AvaloniaPropertyAccessorPlugin.cs @@ -13,7 +13,15 @@ namespace Avalonia.Markup.Data.Plugins public class AvaloniaPropertyAccessorPlugin : IPropertyAccessorPlugin { /// - public bool Match(WeakReference reference) => reference.Target is AvaloniaObject; + public bool Match(object obj, string propertyName) + { + if (obj is AvaloniaObject a) + { + return AvaloniaPropertyRegistry.Instance.FindRegistered(a, propertyName) != null; + } + + return false; + } /// /// Starts monitoring the value of a property on an object. diff --git a/src/Markup/Avalonia.Markup/Data/Plugins/IPropertyAccessorPlugin.cs b/src/Markup/Avalonia.Markup/Data/Plugins/IPropertyAccessorPlugin.cs index 187142bd0e..ebfdf6ebe4 100644 --- a/src/Markup/Avalonia.Markup/Data/Plugins/IPropertyAccessorPlugin.cs +++ b/src/Markup/Avalonia.Markup/Data/Plugins/IPropertyAccessorPlugin.cs @@ -14,9 +14,10 @@ namespace Avalonia.Markup.Data.Plugins /// /// Checks whether this plugin can handle accessing the properties of the specified object. /// - /// A weak reference to the object. - /// True if the plugin can handle the object; otherwise false. - bool Match(WeakReference reference); + /// The object. + /// The property name. + /// True if the plugin can handle the property on the object; otherwise false. + bool Match(object obj, string propertyName); /// /// Starts monitoring the value of a property on an object. diff --git a/src/Markup/Avalonia.Markup/Data/Plugins/InpcPropertyAccessorPlugin.cs b/src/Markup/Avalonia.Markup/Data/Plugins/InpcPropertyAccessorPlugin.cs index 138f09b373..3bdaba6fd9 100644 --- a/src/Markup/Avalonia.Markup/Data/Plugins/InpcPropertyAccessorPlugin.cs +++ b/src/Markup/Avalonia.Markup/Data/Plugins/InpcPropertyAccessorPlugin.cs @@ -19,7 +19,7 @@ namespace Avalonia.Markup.Data.Plugins public class InpcPropertyAccessorPlugin : IPropertyAccessorPlugin { /// - public bool Match(WeakReference reference) => true; + public bool Match(object obj, string propertyName) => true; /// /// Starts monitoring the value of a property on an object. @@ -36,7 +36,7 @@ namespace Avalonia.Markup.Data.Plugins Contract.Requires(propertyName != null); var instance = reference.Target; - var p = instance.GetType().GetRuntimeProperties().FirstOrDefault(_ => _.Name == propertyName); + var p = instance.GetType().GetRuntimeProperties().FirstOrDefault(x => x.Name == propertyName); if (p != null) { @@ -138,7 +138,7 @@ namespace Avalonia.Markup.Data.Plugins if (inpc != null) { - WeakSubscriptionManager.Subscribe( + WeakSubscriptionManager.Subscribe( inpc, nameof(inpc.PropertyChanged), this); diff --git a/src/Markup/Avalonia.Markup/Data/PropertyAccessorNode.cs b/src/Markup/Avalonia.Markup/Data/PropertyAccessorNode.cs index ab80d72215..f6040d3f15 100644 --- a/src/Markup/Avalonia.Markup/Data/PropertyAccessorNode.cs +++ b/src/Markup/Avalonia.Markup/Data/PropertyAccessorNode.cs @@ -37,7 +37,7 @@ namespace Avalonia.Markup.Data protected override IObservable StartListeningCore(WeakReference reference) { - var plugin = ExpressionObserver.PropertyAccessors.FirstOrDefault(x => x.Match(reference)); + var plugin = ExpressionObserver.PropertyAccessors.FirstOrDefault(x => x.Match(reference.Target, PropertyName)); var accessor = plugin?.Start(reference, PropertyName); if (_enableValidation && Next == null)