Is it possible to create a weak event listener on a static event using WeakEventManager?
I would like to create a weak event listener on the static CompositionTarget.Rendering event to avoid memory leaks when I don't know the lifetime of the WPF/Silverlight source element.
I implemented the rendering event manager by the weak event pattern:
public class RenderingEventManager : WeakEventManager
{
public static void AddListener(IWeakEventListener listener)
{
CurrentManager.ProtectedAddListener(null, listener);
}
public static void RemoveListener(IWeakEventListener listener)
{
CurrentManager.ProtectedRemoveListener(null, listener);
}
private static RenderingEventManager CurrentManager
{
get
{
var managerType = typeof(RenderingEventManager);
var manager = (RenderingEventManager)GetCurrentManager(managerType);
if (manager == null)
{
manager = new RenderingEventManager();
SetCurrentManager(managerType, manager);
}
return manager;
}
}
protected sealed override void StartListening(object source)
{
CompositionTarget.Rendering += this.OnCompositionTargetRendering;
}
protected sealed override void StopListening(object source)
{
CompositionTarget.Rendering -= this.OnCompositionTargetRendering;
}
void OnCompositionTargetRendering(object sender, EventArgs e)
{
this.DeliverEvent(sender, e);
}
}
and tested the manager in a simple window:
public partial class Window1 : Window, IWeakEventListener
{
public Window1()
{
InitializeComponent();
RenderingEventManager.AddListener(this);
}
bool IWeakEventListener.ReceiveWeakEvent(Type managerType, object sender, EventArgs e)
{
return true;
}
}
The ReceiveWeakEvent method is not being called. OnCompositionTargetRendering is called, but it seems like DeliverEvent does not work as I expected. Adding listeners to instance events like Button.Click works fine... The test project is on .NET 4.0 Client Profile.
A post on Microsoft Connect from 2009 states that static events are not supported, but I checked the WeakEventManager source code, and it looks ok:
protected void ProtectedAddListener(object source, IWeakEventListener listener)
{
Debug.Assert(listener != null, "Listener cannot be null");
object sourceKey = (source != null) ? source : StaticSource;
...
}
Figured it out myself: change the sender argument of the DeliverEvent method to null:
void OnCompositionTargetRendering(object sender, EventArgs e)
{
this.DeliverEvent(null, e);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With