dotnet/wpf · error · NotSupportedException
SR.NoMulticastHandlers
Error message
SR.NoMulticastHandlers
What it means
ValueChangedEventManager.AddHandler requires a delegate with exactly one target; multicast (combined) delegates are rejected with NotSupportedException(SR.NoMulticastHandlers). The weak-event manager tracks one target per handler and cannot correctly unsubscribe combined delegates.
Solutions
- Register each handler method individually (one AddHandler call per method)
- Split the combined delegate into GetInvocationList() and call AddHandler for each single-target delegate
- Use a lambda or method group that references only one target
Example fix
// before EventHandler<ValueChangedEventArgs> h = OnA; h += OnB; ValueChangedEventManager.AddHandler(source, h, pd); // throws // after ValueChangedEventManager.AddHandler(source, OnA, pd); ValueChangedEventManager.AddHandler(source, OnB, pd);
Defensive patterns
Strategy: validation
Validate before calling
if (handler == null) throw new ArgumentNullException(nameof(handler));
if (handler.GetInvocationList().Length > 1) throw new ArgumentException("Use single-target delegates with ValueChangedEventManager"); Type guard
bool HasSingleTarget(Delegate d) => d is { } && d.GetInvocationList().Length == 1; Try / catch
if (handler.GetInvocationList().Length == 1)
ValueChangedEventManager.AddHandler(source, handler, pd);
else
foreach (EventHandler<ValueChangedEventArgs> h in handler.GetInvocationList())
ValueChangedEventManager.AddHandler(source, h, pd); Prevention
- Never '+=' delegates before weak-event registration
- One AddHandler call per handler method
- Remember weak event managers differ from CLR multicast events
When it happens
Trigger: Calling ValueChangedEventManager.AddHandler(source, handler, pd) where handler was built with Delegate.Combine / '+=' on a local delegate variable, giving it multiple invocation targets.
Common situations: Reusing a shared multicast event-handler field for weak-event registration; refactoring from normal CLR events (which allow multicast) to weak events without splitting handlers.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Event not found: Event 'eventName' not found on type…
- " }} " element found. Expected fixed page element ( }} ).
- ' ' can only host a ' ' or a ' '. ' ' is an invalid…
- ' ' can only host a ' ' or a ' '. ' ' is an invalid…
- ' ' cannot contain the path delimiter: ' '.
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/9818c210bdf3226f.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Data/ValueChangedEventManager.cs:87
/// <summary>
/// Remove a listener to the given source's event.
/// </summary>
public static void RemoveListener(object source, IWeakEventListener listener, PropertyDescriptor pd)
{
ArgumentNullException.ThrowIfNull(source);
ArgumentNullException.ThrowIfNull(listener);
CurrentManager.PrivateRemoveListener(source, listener, pd);
}
/// <summary>
/// Add a handler for the given source's event.
/// </summary>
public static void AddHandler(object source, EventHandler<ValueChangedEventArgs> handler, PropertyDescriptor pd)
{
ArgumentNullException.ThrowIfNull(handler);
if (!handler.HasSingleTarget)
throw new NotSupportedException(SR.NoMulticastHandlers);
CurrentManager.PrivateAddHandler(source, handler, pd);
}
/// <summary>
/// Remove a handler for the given source's event.
/// </summary>
public static void RemoveHandler(object source, EventHandler<ValueChangedEventArgs> handler, PropertyDescriptor pd)
{
ArgumentNullException.ThrowIfNull(handler);
if (!handler.HasSingleTarget)
throw new NotSupportedException(SR.NoMulticastHandlers);
CurrentManager.PrivateRemoveHandler(source, handler, pd);
}
#endregion Public Methods
View on GitHub (pinned to 81131a70a4)