views:

36

answers:

3

In Windows Forms programming, I have this general problem. When the page is loading and populating, in some cases I don't want the logic in the event handlers to run.

The event handling code is primarily to respond to user interaction, but it also runs when the controls are manipulated programmatically. In the past, I've seen people use an IsLoading boolean to protect logic that should only occur in response to user input. This strikes me as a little inelegant, and also the developer has to remember to put it everywhere; this is especially an issue when new features are added.

Lately I've been writing methods to disconnect the event handlers when loading the form, and reconnect them (in a finally clause) afterward. This seems a little better, but I wonder if there is a more elegant way. Anyone have an alternate way of handling this situation?

A: 

The most elegant way to solve this type of issues is to use the Model View Presenter design pattern. Here the background code doesn't fiddle with the state of the controls directly, but alters the model, which then triggers the update of the UI. I the case of WinForms its really hard to implement a proper MVP pattern, but you could use data bindings to separate the state of your application from the actual controls. When you implement binding correctly, after your background code updates the data, it should be automagically displayed in the controls.

Grzenio
Does the framework-level databinding dodge the event handlers on the populated controls? For example the _TextChanged event? We do use a form of MVC for these forms but my experience is the very act of populating the control in any way typically fires the event handlers.
Jason
A: 

I think this question is related, and will be of interest to you:

WinForms: temporarily disable an event handler

Philip Wallace
Right - I know how to do so, but the question is whether that's the best pattern.
Jason
+1  A: 

There's no "right" answer here, but I agree with your approach and have used it numerous times. While it is nice that my events get triggered no matter how a widget gets modified, sometimes this is exactly what I want to avoid. I have often written DisableFooEventHandlers()/EnableFooEventHandlers() pairs of methods in my forms. This makes it clear to someone viewing the code what I am trying to accomplish. I try to use these in matched method/event setups, for example:

void BeginBulkProcessing()
{
    DisbaleFooEventHandlers();
    ...
}

void OnBulkProcessingComplete()
{
    ...
    EnableFooEventHandlers();
}

Not glamorous, but it serves the purpose and it's clear what is going on here. I have yet to find anything better, since in the end, only I (the programmer) know when I should suspend the processing and this is easily traceable.

cdkMoose