views:

1138

answers:

5

This seems like a very simple and a very common problem. The simplest example I can think of is this. The form has 5 checkboxes with a "check all/check none" checkbox above them. When a user selects the check all checkbox I toggle the states of the "children" - obviously I don't want to fire the check events of all the children until I am done setting all of the checkboxes.

I can't find a form-wide suspend control events. If I'm simply missing it then great simple answer. Barring a simple solution that I am just missing what is the best way (best practice? accepted solution?) to suspend form control events?

+2  A: 

From your other question, I'm going to guess you're using VB .NET. So, RemoveHandler is your best bet. Normally in VB people set up event handlers using the Handles clause. But you can also do it this way:

AddHandler chk1.CheckedChanged, AddressOf DoSomething

where DoSomething might look like this:

Private Sub DoSomething(ByVal sender As Object, ByVal e As EventArgs)
    ' whatever
End Sub

AddHandler wires up the event, so it'll fire. To get it not to fire, use RemoveHandler:

RemoveHandler chk1.CheckedChanged, AddressOf DoSomething

Before updating the Checked property of your child checkboxes, call RemoveHandler on each of them; then when you're done, call AddHandler to put the event handlers back. If all your checkboxes use the same handler, you can put them in a collection and loop through the collection to add or remove the handlers.

Kyralessa
+3  A: 

I've come across this before and usually seen people do this:

/*SNIP*/

private bool isMassUpdate;

public void Check1_Check(object sender, EventArgs e)
{
   if(!isMassUpdate)
   {
       do some stuff
   }
}

/*SNIP*/

You can also detach and reattach the event handlers, however, I'm told this can be a source of memory leaks.

EDIT: Info on memory leaks and event handlers. They're not directly linked to attaching and detaching but we've seen in one of our apps that bad referencing of event handlers down inheritance trees can cause it.

http://blogs.msdn.com/tess/archive/2006/01/23/net-memory-leak-case-study-the-event-handlers-that-made-the-memory-baloon.aspx

http://forum.umbraco.org/yaf_postst6558_Net-Experts-Question-on-Event-Handlers-and-Memory-Leaks.aspx

Rob Stevenson-Leggett
+1  A: 

You could also consider handling 'click' events for the buttons, rather than check-changed. That might be nearer to your intent.

Will Dean
Thanks and true makes sense here but this is more of a general question and the above example is just that, an example. I just run into the scenario many times where I would like control events to halt while I do something and am just curious as to the best practice.
Steve Bargelt
A: 

In my VB6 app I had to handle users double-clicking everything so on all my event handlers I have one line that checks a global variable

Private bSuspendEvents as Boolean

Private Sub Button1_Click()

  On Error Goto ErrorHandler

  If bSuspendEvents then Exit Sub

  bSuspendEvents = True

  'Do stuff

NormalExit:
  bSuspendEvents = False
  Exit Sub

ErrorHandler:
  'Handle Error
  Resume NormalExit

End Sub
DJ
+2  A: 

What I do in these cases instead of having a boolean value that suspends events, I use a counter. When the count is > 0, then suspend events, when the count = 0, then resume events. This helps with the problem if I have multiple things that could request a suspension of events.

The other useful thing is if I need to suspend events in a block, I create a little helper class that is IDisposable that I can use in a "using" block (in C#) so I don't forget to decrement the counter once I'm out of scope.

Garo Yeriazarian