Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handled PropertyChanged event with WeakEventManager #73

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 57 additions & 1 deletion MvvmHelpers.UnitTests/WeakEventManagerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
{
Expand Down Expand Up @@ -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()
{
Expand Down Expand Up @@ -221,4 +277,4 @@ public void VerifySubscriberCanBeCollected()
source.FireTestEvent();
}
}
}
}
14 changes: 9 additions & 5 deletions MvvmHelpers/ObservableObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ namespace MvvmHelpers
/// </summary>
public class ObservableObject : INotifyPropertyChanged
{
readonly WeakEventManager weakEventManager = new WeakEventManager();

/// <summary>
/// Sets the property.
/// </summary>
Expand Down Expand Up @@ -44,15 +46,17 @@ protected virtual bool SetProperty<T>(
/// <summary>
/// Occurs when property changed.
/// </summary>
public event PropertyChangedEventHandler? PropertyChanged;
public event PropertyChangedEventHandler PropertyChanged
{
add { weakEventManager.AddPropertyChangedEventHandler(value); }
remove { weakEventManager.RemovePropertyChangedEventHandler(value); }
}

/// <summary>
/// Raises the property changed event.
/// </summary>
/// <param name="propertyName">Property name.</param>
protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = "") =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

weakEventManager.HandleEvent(this, new PropertyChangedEventArgs(propertyName), nameof(PropertyChanged));
}
}

}
33 changes: 33 additions & 0 deletions MvvmHelpers/WeakEventManager.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Runtime.CompilerServices;

Expand Down Expand Up @@ -48,6 +49,22 @@ public void AddEventHandler(EventHandler handler, [CallerMemberName]string event
AddEventHandler(eventName, handler.Target, handler.GetMethodInfo());
}

/// <summary>
/// Adds an property changed event handler to the manager.
/// </summary>
/// <param name="handler">Handler of the event</param>
/// <param name="eventName">Name to use in the dictionary. Should be unique.</param>
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());
}

/// <summary>
/// Handle an event
/// </summary>
Expand Down Expand Up @@ -129,6 +146,22 @@ public void RemoveEventHandler(EventHandler handler, [CallerMemberName]string ev
RemoveEventHandler(eventName, handler.Target, handler.GetMethodInfo());
}

/// <summary>
/// Remove an event handler.
/// </summary>
/// <param name="handler">Handler to remove</param>
/// <param name="eventName">Event name to remove</param>
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))
Expand Down