/// <summary> /// Registers an event handler that works with a weak reference to the target object. /// Access to the event and to the real event handler is done through lambda expressions. /// The code holds strong references to these expressions, so they must not capture any /// variables! /// </summary> /// <example> /// <code> /// WeakEventHandler.Register( /// textDocument, /// (d, eh) => d.Changed += eh, /// (d, eh) => d.Changed -= eh, /// this, /// (me, sender, args) => me.OnDocumentChanged(sender, args) /// ); /// </code> /// </example> public static WeakEventHandler Register <TEventSource, TEventListener>( TEventSource senderObject, ZetaAction <TEventSource, EventHandler> registerEvent, ZetaAction <TEventSource, EventHandler> deregisterEvent, TEventListener listeningObject, ZetaAction <TEventListener, object, EventArgs> forwarderAction ) where TEventSource : class where TEventListener : class { if (senderObject == null) { throw new ArgumentNullException(nameof(senderObject)); } if (listeningObject == null) { throw new ArgumentNullException(nameof(listeningObject)); } VerifyDelegate(registerEvent, @"registerEvent"); VerifyDelegate(deregisterEvent, @"deregisterEvent"); VerifyDelegate(forwarderAction, @"forwarderAction"); var weh = new WeakEventHandler(listeningObject); var eh = weh.MakeDeregisterCodeAndWeakEventHandler(senderObject, deregisterEvent, forwarderAction); registerEvent(senderObject, eh); return(weh); }
EventHandler MakeDeregisterCodeAndWeakEventHandler <TEventSource, TEventListener> ( TEventSource senderObject, ZetaAction <TEventSource, EventHandler> deregisterEvent, ZetaAction <TEventListener, object, EventArgs> forwarderAction ) where TEventSource : class where TEventListener : class { EventHandler eventHandler = null; DeregisterCode = () => deregisterEvent(senderObject, eventHandler); eventHandler = (sender, args) => { var listeningObject = (TEventListener)ListeningReference.Target; if (listeningObject != null) { forwarderAction(listeningObject, sender, args); } else { Deregister(); } }; return(eventHandler); }
/// <summary> /// Deregisters the event handler. /// </summary> public void Deregister() { if (DeregisterCode != null) { DeregisterCode(); DeregisterCode = null; } }