EventHandler weak bei normalen Events registrieren

Events sind für die Garbage Collection in C# immer eine gewisse Herausforderung. Da der Garbagecollector nur Elemente beseitigt, auf die keine Referenzen mehr bestehen, kann ein registrierter EventHandler zu einem Speicherleck führen. Dies umgeht man in .Net durch ein Weak Event. Die gängigen Lösungen für das Problem gehen meist davon aus, dass man ein Event als ein solches WeakEvent anlegt wodurch sich Objekte nicht anpassen müssen, die einen Eventhandler bei dem Event registrieren. Doch wie geht man vor wenn man einen Eventhandler weak bei einem normalen Event registrieren möchte?

Gehen wir davon aus, dass wir einen Eventhandler bei einem WPF Frameworkelement registrieren wollen. Dieses Frameworkelement bietet für uns die Herausforderung, dass wir es nicht modifizieren können.


// Enventhandler

private  void OnRequestBringIntoView(object sender, RequestBringIntoViewEventArgs e)
{
...
}

Um den Eventhandler zu registrieren brauchen wir ihn auf unserem Element (ScrollViewer) nur per += dem entsprechenden Event hinzuzufügen. Ein WeakEvent oder eine WeakReferenz lässt sich hierbei nicht übergeben, da es einfach nicht die korrekten Datentypen sind.


this.scollViewer.RequestBringIntoView += this.OnRequestBringIntoView;

Um die Registrierung nun weak vorzunehmen, benötigen wir den WeakEventManager<T>. Diesen sollte man nicht mit der Version ohne generischen Datentyp verwechseln. Jene stellt nur eine abstrakte Basisklasse dar, die man selbst implementieren muss. Die typisierte Variante bietet vor allem statische Methoden wie AddHandler und RemoveHandler. Mit diesen registriert oder entfernt man den Handler unter Angabe  der Instanz bei der registriert werden soll, dem Namen des Events und der Referenz auf den eigentlichen Handler.


WeakEventManager<ScrollViewer, RequestBringIntoViewEventArgs>.AddHandler(this.scrollViewer, "RequestBringIntoView", OnRequestBringIntoView);