Is there a generally-accepted best practice for creating an event handler that unsubscribes itself?
E.g., the first thing I came up with is something like:
// Foo.cs
// ...
Bar bar = new Bar(/* add'l req'd state */);
EventHandler handler = new EventHandler(bar.HandlerMethod);
bar.HandlerToUnsubscribe = handler;
eventSource.EventName += handler;
// ...
// Bar.cs
class Bar
{
/* add'l req'd state */
// .ctor
public EventHandler HandlerToUnsubscribe { get; set; }
public void HandlerMethod(object sender, EventArgs args)
{
// Do what must be done w/ add'l req'd state
((EventSourceType)sender).EventName -= this.HandlerToUnsubscribe;
}
}
To say that this feels hackish/bad is an understatement. It's tightly coupled with a temporal dependency (HandlerToUnsubscribe
must be assigned the exact value at the exact right time). I feel like I must be playing the part of a complicator in this case--- is there something stupid or simple that I'm missing?
Context:
I'm creating a binding between the UI and a proprietary commanding infrastructure in Winforms (using the useful ICommand
in System.Windows.Input). One aspect of the binding infrastructure is that users who create a binding between a UI command component (like a toolbar button or menu item) have the option to listen to the command's CanExecuteChanged
event and then update the UI's state based on that-- typically setting the Enabled property to true
or false
.
The technique generally works quite well, but there are ways for the event to be fired prior to a ui component's handle having been created. I'm trying to guarantee that the provided handler isn't run unless the handle has been created. Resultantly, I'm considering providing a general helper class ("Bar
") that will aid implementation. The goal of Bar
is to check to see if the appropriate handle exists. If so, great! If not, it will subscribe to appropriate IsHandleCreated
event so that the supplied handlers get run when the handle eventually is created. (This is important b/c the client may set their bindings in the UI's .ctor, before a handle exists.) I want this subscription to be completely transparent, however, and so I also want each event handler to automatically unsubscribe itself from IsHandleCreated
once it's finished running.
I'm still at a point where I'm trying to figure out if this is a good idea, so I haven't generalized the concept yet-- I've only implemented it directly against ToolStripItems in this case to verify that the idea is sound. I'm not sold on it yet, though.
I understand that I also have the option of simply mandating that bindings can only be created once the UI's handle has been created, in the OnLoad event of a form (e.g.). I know that can work, I've done it in the past. I'd like to see if I can ease that particular requirement in this case though. If it's even practical.