This snippet will help you if you need to cleanup events. In a normal way, you have to use += or -=, or use WeakEventHandler().AddHandler or RemoveHandler. But sometimes, you could need a harder way!
Introduction
We had the need to cleanup a WPF Visual tree on windows closing. To do that, we developed a WPF Behavior on the Window component.
On closing, this behavior just ran across the visual tree of the window. Take each component and to this:
- Clear all bindings
- Clear all event listeners (static or not)
- Set the
dataContext
to null
This helps the GC to collect speedily...
Using the Code
The code to do the clear events part is the following:
public static void ClearEvents(object instance)
{
var eventsToClear = instance.GetType().GetEvents(
BindingFlags.Public | BindingFlags.NonPublic
| BindingFlags.Instance | BindingFlags.Static);
foreach (var eventInfo in eventsToClear)
{
var fieldInfo = instance.GetType().GetField(
eventInfo.Name,
BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
if (fieldInfo.GetValue(instance) is Delegate eventHandler)
foreach (var invocatedDelegate in eventHandler.GetInvocationList())
eventInfo.GetRemoveMethod(fieldInfo.IsPrivate).Invoke(
instance,
new object[] { invocatedDelegate });
}
}
Points of Interest
Reflection is a very powerful tool, but this must not be the main way. This must only be used in critical scenarios.
Be careful of that!
History
- 29th September, 2021: Version 1