
How to Implement the WeakEvent Pattern
Implementing the WeakEvent pattern consists of three aspects:
-
Derive a manager from the WeakEventManager class.
-
Implement the IWeakEventListener interface on any class that wants to register listeners for the weak event without generating a strong reference to the source.
-
When registering listeners, do not use the conventional add and remove accessors of the event where you want the listener to use the pattern. Instead, use the "AddListener" and "RemoveListener" implementations in the dedicated WeakEventManager for that event.
WeakEventManager
Typically, you will create manager classes at a 1:1 relationship to events that implement the pattern. For instance, if you have an event Spin, you would derive a SpinEventManager class as the dedicated weak event manager for the event. If the event existed in more than one source class, and behaved generally the same in each class and shared the event data type, the same manager could be used for each.
The implementation checklist for deriving from the WeakEventManager class consists of overriding two virtual methods, and exposing several other members whose names are not specifically governed by a virtual template, but should exist nonetheless. The overrides are used to initiate or terminate event delivery mode by the WPF infrastructure. The other members are necessary to provide functionality so that your own IWeakEventListener implementations can use the WeakEventManager to attach listeners to the event.
For detailed implementation notes for deriving from WeakEventManager, see "Notes to Inheritors" in the WeakEventManager reference topic.
IWeakEventListener
Attaching Listeners
Suppose you had a ClockwiseSpin event (defined by Spinner) that is a conventional event. To use the pattern for this event, you would either use an existing ClockwiseSpinEventManager class derived from WeakEventManager, or implement it yourself. If you have a SpinListener listener class that wants to be a listener, the conventional technique (not using the pattern) for attaching the handler would to use the += syntax:
spinnerInstance.ClockwiseSpin += new EventHandler(MyOnCWSpinHandler);
But if you have a class that implements IWeakEventListener and accounts for the ClockwiseSpin event and its manager in the implementation, the syntax to use instead for the WeakEvent pattern is:
ClockwiseSpinEventManager.AddListener(spinnerInstance, this);
Then, your handling logic for that event is specified within one of the cases of the ReceiveWeakEvent implementation on your class, not as a conventional delegate-based handler.
Implementing the Pattern for External Events
One interesting aspect of the WeakEvent pattern is that you can implement the pattern against an event that is not part of your code base. From the perspective of the source, the way that handlers are attached to its event does not differ, and is controlled by the WeakEventManager. You only need to define a WeakEventManager for that event, and then account for that event as part of the ReceiveWeakEvent logic on any prospective listener that wants to use the pattern to listen to that event.