-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Description
WeakEventManager
Microsoft.Maui.Controls.WeakEventManger only supports event EventHandler.
It does not currently work with the other event types in C#, like Delegate.
This means that Microsoft.Maui.Controls.WeakEventManger does not currently work for the most common Delegate event, INotifyPropertyChanged.PropertyChanged.
Because EventHandler is a Delegate, we can expand WeakEventManager, adding support for Delegate without any breaking changes.
Working Example
For EventHandler events, Microsoft.Maui.Controls.WeakEventManger works great!
readonly WeakEventManager weakEventManager = new WeakEventManager();
public event EventHandler Completed
{
add => weakEventManager.AddEventHandler(value);
remove => weakEventManager.RemoveEventHandler(value);
}
void OnCompleted() => weakEventManager.HandleEvent(this, EventArgs.Empty, nameof(Completed));Non-Working Example
For delegate events, Microsoft.Maui.Controls.WeakEventManger is not compatible.
readonly WeakEventManager weakEventManager = new WeakEventManager();
event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
{
add => weakEventManager.AddEventHandler(value); // Compiler Error
remove => weakEventManager.RemoveEventHandler(value); // Compiler Error
}
void OnPropertyChanged([CallerMemberName] in string propertyName = "") => weakEventManager.HandleEvent(this, new PropertyChangedEventArgs(propertyName), nameof(INotifyPropertyChanged.PropertyChanged));Xamarin Community Toolkit, DelegateWeakEventManager
The Xamarin.CommunityToolkit has expanded on WeakEventManager, adding support for delegate events:
https://docs.microsoft.com/xamarin/community-toolkit/helpers/delegateweakeventmanager?WT.mc_id=mobile-43581-bramin
This feature was named DelegateWeakEventManager to avoid a name-collision with WeakEventManager despite providing (almost) the exact same feature set; the only difference is the additional support for delegate events.
The Xamarin Community Toolkit has included this expanded WeakEventManager since v1.0.0-pre4 released on October 21, 2020.
We currently have an open proposal to add this functionality to Maui Community Toolkit, but we'd prefer to promote this feature into the official .NET MAUI library.
API Changes
WeakEventManager
Methods
Current
The current implementation only supports EventHandler
public void AddEventHandler(EventHandler handler, [CallerMemberName] string eventName = null)
{
if (IsNullOrEmpty(eventName))
throw new ArgumentNullException(nameof(eventName));
if (handler == null)
throw new ArgumentNullException(nameof(handler));
AddEventHandler(eventName, handler.Target, handler.GetMethodInfo());
}
public void RemoveEventHandler(EventHandler handler, [CallerMemberName] string eventName = null)
{
if (IsNullOrEmpty(eventName))
throw new ArgumentNullException(nameof(eventName));
if (handler == null)
throw new ArgumentNullException(nameof(handler));
RemoveEventHandler(eventName, handler.Target, handler.GetMethodInfo());
}Updated
The updated implementation adds support for Delegate
public void AddEventHandler(Delegate? handler, [CallerMemberName] string eventName = null)
{
ArgumentNullException.ThrowIfNull(eventName);
ArgumentNullException.ThrowIfNull(handler)
var methodInfo = handler.GetMethodInfo() ?? throw new NullReferenceException("Could not locate MethodInfo");
AddEventHandler(eventName, handler.Target, methodInfo, eventHandlers);
}
public void RemoveEventHandler(Delegate? handler, [CallerMemberName] string eventName = "")
{
ArgumentNullException.ThrowIfNull(eventName);
ArgumentNullException.ThrowIfNull(handler)
var methodInfo = handler.GetMethodInfo() ?? throw new NullReferenceException("Could not locate MethodInfo");
RemoveEventHandler(eventName, handler.Target, methodInfo, eventHandlers);
}Scenarios
C# Example
The most common usage of a delegate event is implementing INotifyPropertyChanged:
readonly WeakEventManager weakEventManager = new WeakEventManager();
event PropertyChangedEventHandler? INotifyPropertyChanged.PropertyChanged
{
add => weakEventManager.AddEventHandler(value);
remove => weakEventManager.RemoveEventHandler(value);
}
void OnPropertyChanged([CallerMemberName] in string propertyName = "") => weakEventManager.HandleEvent(this, new PropertyChangedEventArgs(propertyName), nameof(INotifyPropertyChanged.PropertyChanged));XAML Example
N/A
CSS Example
N/A
Backward Compatibility
Because EventHandler is a Delegate, this update is completely backwards compatible and does not introduce any breaking changes.
Minimum API levels? None
Breaking changes? None
Unsupported platforms? None
Difficulty : Low
I am happy to open a PR to implement this feature