From 1d282f564aee264e799ba541d485074f589c7f73 Mon Sep 17 00:00:00 2001 From: "curia.damiano" Date: Mon, 24 Aug 2020 10:53:11 +0200 Subject: [PATCH] Handled PropertyChanged event with WeakEventManager --- .../WeakEventManagerTests.cs | 58 ++++++++++++++++++- MvvmHelpers/ObservableObject.cs | 14 +++-- MvvmHelpers/WeakEventManager.cs | 33 +++++++++++ 3 files changed, 99 insertions(+), 6 deletions(-) diff --git a/MvvmHelpers.UnitTests/WeakEventManagerTests.cs b/MvvmHelpers.UnitTests/WeakEventManagerTests.cs index 0f32b93..9fbbc24 100644 --- a/MvvmHelpers.UnitTests/WeakEventManagerTests.cs +++ b/MvvmHelpers.UnitTests/WeakEventManagerTests.cs @@ -77,6 +77,30 @@ public void AddHandlerWithNullEventNameThrowsException() wem.AddEventHandler((sender, args) => { }, null); } + [TestMethod] + [ExpectedException(typeof(ArgumentNullException))] + public void AddPropertyChangedHandlerWithEmptyEventNameThrowsException() + { + var wem = new WeakEventManager(); + wem.AddPropertyChangedEventHandler((sender, args) => { }, ""); + } + + [TestMethod] + [ExpectedException(typeof(ArgumentNullException))] + public void AddPropertyChangedHandlerWithNullEventHandlerThrowsException() + { + var wem = new WeakEventManager(); + wem.AddPropertyChangedEventHandler(null, "test"); + } + + [TestMethod] + [ExpectedException(typeof(ArgumentNullException))] + public void AddPropertyChangedHandlerWithNullEventNameThrowsException() + { + var wem = new WeakEventManager(); + wem.AddPropertyChangedEventHandler((sender, args) => { }, null); + } + [TestMethod] public void CanRemoveEventHandler() { @@ -170,6 +194,38 @@ public void RemovingNonExistentHandlersShouldNotThrow() wem.RemoveEventHandler(Handler, "alsofake"); } + [TestMethod] + [ExpectedException(typeof(ArgumentNullException))] + public void RemovePropertyChangedHandlerWithEmptyEventNameThrowsException() + { + var wem = new WeakEventManager(); + wem.RemovePropertyChangedEventHandler((sender, args) => { }, ""); + } + + [TestMethod] + [ExpectedException(typeof(ArgumentNullException))] + public void RemovePropertyChangedHandlerWithNullEventHandlerThrowsException() + { + var wem = new WeakEventManager(); + wem.RemovePropertyChangedEventHandler(null, "test"); + } + + [TestMethod] + [ExpectedException(typeof(ArgumentNullException))] + public void RemovePropertyChangedHandlerWithNullEventNameThrowsException() + { + var wem = new WeakEventManager(); + wem.RemovePropertyChangedEventHandler((sender, args) => { }, null); + } + + [TestMethod] + public void RemovingPropertyChangedNonExistentHandlersShouldNotThrow() + { + var wem = new WeakEventManager(); + wem.RemovePropertyChangedEventHandler((sender, args) => { }, "fake"); + wem.RemoveEventHandler(Handler, "alsofake"); + } + [TestMethod] public void RemoveHandlerWithMultipleSubscriptionsRemovesOne() { @@ -221,4 +277,4 @@ public void VerifySubscriberCanBeCollected() source.FireTestEvent(); } } -} +} \ No newline at end of file diff --git a/MvvmHelpers/ObservableObject.cs b/MvvmHelpers/ObservableObject.cs index a84feef..5dd2e07 100644 --- a/MvvmHelpers/ObservableObject.cs +++ b/MvvmHelpers/ObservableObject.cs @@ -10,6 +10,8 @@ namespace MvvmHelpers /// public class ObservableObject : INotifyPropertyChanged { + readonly WeakEventManager weakEventManager = new WeakEventManager(); + /// /// Sets the property. /// @@ -44,15 +46,17 @@ protected virtual bool SetProperty( /// /// Occurs when property changed. /// - public event PropertyChangedEventHandler? PropertyChanged; + public event PropertyChangedEventHandler PropertyChanged + { + add { weakEventManager.AddPropertyChangedEventHandler(value); } + remove { weakEventManager.RemovePropertyChangedEventHandler(value); } + } /// /// Raises the property changed event. /// /// Property name. protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = "") => - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - + weakEventManager.HandleEvent(this, new PropertyChangedEventArgs(propertyName), nameof(PropertyChanged)); } -} - +} \ No newline at end of file diff --git a/MvvmHelpers/WeakEventManager.cs b/MvvmHelpers/WeakEventManager.cs index 1961917..1ab7f1b 100644 --- a/MvvmHelpers/WeakEventManager.cs +++ b/MvvmHelpers/WeakEventManager.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Reflection; using System.Runtime.CompilerServices; @@ -48,6 +49,22 @@ public void AddEventHandler(EventHandler handler, [CallerMemberName]string event AddEventHandler(eventName, handler.Target, handler.GetMethodInfo()); } + /// + /// Adds an property changed event handler to the manager. + /// + /// Handler of the event + /// Name to use in the dictionary. Should be unique. + public void AddPropertyChangedEventHandler(PropertyChangedEventHandler handler, [CallerMemberName] string eventName = "PropertyChanged") + { + if (IsNullOrEmpty(eventName)) + throw new ArgumentNullException(nameof(eventName)); + + if (handler == null) + throw new ArgumentNullException(nameof(handler)); + + AddEventHandler(eventName, handler.Target, handler.GetMethodInfo()); + } + /// /// Handle an event /// @@ -129,6 +146,22 @@ public void RemoveEventHandler(EventHandler handler, [CallerMemberName]string ev RemoveEventHandler(eventName, handler.Target, handler.GetMethodInfo()); } + /// + /// Remove an event handler. + /// + /// Handler to remove + /// Event name to remove + public void RemovePropertyChangedEventHandler(PropertyChangedEventHandler handler, [CallerMemberName] string eventName = "") + { + if (IsNullOrEmpty(eventName)) + throw new ArgumentNullException(nameof(eventName)); + + if (handler is null) + throw new ArgumentNullException(nameof(handler)); + + RemoveEventHandler(eventName, handler.Target, handler.GetMethodInfo()); + } + void AddEventHandler(string eventName, object handlerTarget, MethodInfo methodInfo) { if (!eventHandlers.TryGetValue(eventName, out var targets))