שתף באמצעות


Temporarily disable events for a control...

Question

Tuesday, November 13, 2007 11:00 PM

Hi there... I'd like to temporarily disable events for a given control. For example, the SelectionChanged event on a combobox might be used to update a display every time the user changes the combobox... but while I'm filling the combobox with values, I don't want the SelectionChanged event to be firing over and over... I need to disable events while the combobox is being populated. How do I do this?

WATYF

All replies (13)

Wednesday, November 14, 2007 7:58 PM ✅Answered

The best way I've found to do this is to use a class-scope flag variable that is checked at the start of every control event you want to keep from firing.  It's kind of a pain but it does work well - especially when you are doing a cluster of settings like populating a form's controls with data.  By not including the bypass then you can be sure that certain events do fire every time.  Also, in teh case of teh combobox you can use the SelectionChangeCommitted event becuase it only fires off when the user selects an item from the list (not when you do it programmatically).

 

Code Block

Public Class Form1

 

Private ControlBypass As String = False

 

Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _

Handles ComboBox1.SelectedIndexChanged

If ControlBypass Then Return

 

If ComboBox1.SelectedIndex > 0 Then

   ControlBypass = True

   ComboBox1.SelectedIndex -= 1

   ControlBypass = False

End If

End Sub

 

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

For x As Int32 = 0 To 5

   ComboBox1.Items.Add("Item " & x)

Next

End Sub

 

End Class

 

 

 


Tuesday, November 13, 2007 11:24 PM

This should work:

To lock the control.
        ComboBox1.Enabled = False

To unlock it again.
        ComboBox1.Enabled = True

hth,
Olice


Wednesday, November 14, 2007 6:06 PM

Really? I did not know that disabling a control turned off it's events. I will try that. Thanks.

WATYF


Wednesday, November 14, 2007 7:00 PM

***... that didn't work. The event still fires. Any other ideas?

WATYF


Wednesday, November 14, 2007 7:29 PM

I placed a combobox on a form and used ocertain's code like so, and it worked just fine:

 

Code Block

Public Class Form1

 Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged

  MsgBox("changed")

 End Sub

 Private Sub LoadCombo()

  For i As Integer = 0 To 9

   Me.ComboBox1.Items.Add("Item " & i)

  Next

 End Sub

 Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

  Me.ComboBox1.Enabled = False

  LoadCombo()

  Me.ComboBox1.Enabled = True

 End Sub

End Class

 

 

could you post the code of what you're trying to do?


Wednesday, November 14, 2007 7:32 PM

Yeah, sorry... I said "load the combobox", but technically "loading" items into it isn't what fires the event. After the load is done, I select the topmost item in the combobox (so it's not set to nothing). When I do that, then the event fires.

WATYF


Thursday, November 15, 2007 6:49 PM

Yeah, I've always used a public variable to accomplish this type of thing... I was just wondering if there was a cleaner way to do it. It looks like there isn't, though, so I just went back to using a variable flag.

WATYF


Thursday, November 15, 2007 6:58 PM

I suppose if you were to use custom controls that implement an interface with a Bypass property or just plain have the property then you could use those controls instead of the standard ones.  You should still be able to plop on to the designer as User Controls like any other control.

 


Wednesday, August 13, 2008 4:39 PM

Although using a public variable will solve custom issues, it won't help for generic solutions. For example if you have a combobox listing customers which is used in lots of different forms in a project and call a child form to allow user to change customer information and go back to parent form containing the combobox you'll need to clear and refill the contents of combobox as the user probably changes some data that will effect the appearance of data in combo. You need to exactly know which form the call was made and this is something messy. So you can try something else in these situations. You can use the TAG property of combobox to communicate with calling form with combobox so that when the tag property is set to true you can exit the SelectedIndexChanged subroutine. When the child form needs to refill the combobox all it has to do is setting the tag value to true during operation and false when done. Here is an example:

 

If Not IsNothing(Me.Owner) Then 
    Dim tbMusteriler As DataTable, rowSatir As DataRow, foUstForm As Form, iKodMusteri As ComboBox, coKontrol As Control  
    Dim obEleman As clListeEleman  
 
    'Open table - it uses a function i wrote, you can use your own method, it is irrelevant  
 
    tbMusteriler = TabloAc("SELECT * FROM tbMusteriler WHERE bTip=0 ORDER BY sUnvan", Me.Owner)  
    foUstForm = Me.Owner.ActiveMdiChild    'This code runs on a project with a main page of MDI parent. That's why it refers to ActiveMDIChild. You can change this according to your form hierarchy  
    coKontrol = foUstForm.Controls.Find("iKodMusteri", False)(0)    'Find the combobox to refill  
    iKodMusteri = CType(coKontrol, ComboBox)  
    iKodMusteri.Tag = True    'Set tag to true to stop SelectedIndexChangedEvent of combo  
    iKodMusteri.SuspendLayout()    'Optional, irrelevant  
    iKodMusteri.Items.Clear()  
    iKodMusteri.Text = "" 
    For Each rowSatir In tbMusteriler.Rows  
        obEleman = New clListeEleman(rowSatir("sUnvan"), rowSatir("aKod"))    'Use a class to add value-text members  
        iKodMusteri.Items.Add(obEleman)  
        If rowSatir("aKod") = vKodMusteri Then    'If current item is equal to the record currently being edited, select it. vKodMusteri is a public variable defined at top of that form's code and is set to combobox's selected value  
            iKodMusteri.SelectedIndex = iKodMusteri.Items.Count - 1  
            iKodMusteri.Text = rowSatir("sUnvan")  
        End If 
    Next 
    iKodMusteri.ResumeLayout()  
    iKodMusteri.Tag = False    'Set tag to false to enable SelectedIndexChangedEvent  
End If 
 

And here is the SelectedIndexChanged code of combo

Private Sub iKodMusteri_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles iKodMusteri.SelectedIndexChanged  
    If iKodMusteri.Tag = True Then Exit Sub    'When tag property is set to true by the code above, this line will exit the sub without executing the code below  
.  
. Your code to be run when selected index is changed  
.  
End Sub 

Wednesday, August 13, 2008 4:58 PM

Hi

You can disable events to the combobox by doing the following; i presume you have a bindingsource bound to the combobox

Me

.bindinsource.RaiseListChangedEvents = false

then 

Me**.bindinsource.RaiseListChangedEvents = TRUE
**

Thanks
G Rusher


Wednesday, August 13, 2008 8:11 PM

Good Idea G Rusher.  For that matter you could use the SuspendBinding and resumeBinding properties on teh binding source to accomplish the same goal.  I haven't tried it but it might work here.

Yalin:  Using the Tag property is just a notch better than using a public variable -- at least it's tied to a specific control -- but it still falls in the category of what the OP was trying to avoid.  This is why my original advice wasn't really the ideal solution either.


Monday, August 23, 2010 12:42 PM

Thanx,

You given a great solution.


Sunday, November 17, 2019 12:38 PM | 1 vote

Disabling ComboBox (see ocertain's post above) almost works.

The event will still fire, but nothing will happen if you wrap your code (in the sub that is called when the event fires) within an if clause:

If .ComboBox.Enabled then

End if

Kinda like the public variable or tag solutions, but cleaner.