How To: Setting an Event flag

There are times when you will need to set a flag that will allow you to bypass the native Events. For example, suppose you have code in the SelChange event of your TextArea, and you have code elsewhere that manipulates the text and restores the selection, but you don’t want that to be considered a SelChange. What’s the best practice?

The (too) simple answer is, create a boolean property and set it to true before you run your code. It would look something like this:

Event SelChange()
  if not me.DisableSelChange then
    // Run the SelChange code
  end if
End Event

Sub DoSomething() 
  DisableSelChange = True
  me.Text= "something else" // Ordinarily would trigger SelChange
  DisableSelChange = False
End Sub

The issue arises if you try to call other methods within DoSomething that also sets the DisableSelChange property:

Sub DoMoreStuff()
  DisableSelChange = true
    // Do things that bypass SelChange
  DisableSelChange = false
End Sub

Sub DoSomething()
  DisableSelChange = true
  DoMoreStuff()
    // Now DisableSelChange is set to false, so SelChange will be active ...
  me.Text = "something else" // ... and the SelChange code will run, even though you didn't want it to
  DisableSelChange = false
End Sub

The way around this problem is to use a counter instead of a boolean, but that would become unwieldily since you’d have to constantly check the value of the counter before manipulating it.

The answer is a counter combined with a computed property that returns a boolean:

Property DisableSelChange As Boolean
  Get
    return mDisableSelChange > 0
  End Get
  Set ( value as boolean )
    if value then
      mDisableSelChange = mDisableSelChange + 1
    else
      mDisableSelChange = mDisableSelChange - 1
    end if
    if mDisableSelChange < 0 then mDisableSelChange = 0 // Make sure it's not less than 0 no matter what
  End Set

Within your methods, all you have to do is make sure that every call to DisableSelChange = true is matched with DisableSelChange = false, and your flag will always be right.

The “Too Simple” approach is essentially what I use. I have a NoUpdate As Boolean property of my window that I check in the event handler code of my various controls to prevent “actual” things from happening. You can put portions of code before the “check” (e.g. code for updating other UI elements, etc.) and then the heavy lifting code after the check. This way if you’re setting the value programmatically (with NoUpdate set to True), it’s not the same as when the user makes a change to the control to set the property themselves. Just remember to always set NoUpdate back to False after making whatever programatic changes you need.

Forgot to mention the part that might be the solution to the problem you mentioned:

Sub DoSomething()

NoUpdate = True
DoMoreStuff
NoUpdate = False

End Sub

Sub DoMoreStuff()

Dim oldNoUpdate As Boolean = NoUpdate

NoUpdate = True
'Do something that would result in the control event being fired
NoUpdate = oldNoUpdate

End Sub