19

I wrote a method to handle a comboBox's SelectedIndexChanged event.

In the constructor I populated the comboBox, and this activated my event-handling method. Which I don't want since nobody clicked on the comboBox.

Is there an easy way to get the comboBox not to fire the event unless the user clicked it?

If that is not possible, is there a way to disconnect the event to the method temporarily? Could I just set "my_combo.SelectedIndexChanged = null" and then create a new System.EventHandler?

Or I guess I could create some kind of boolean member variable that I can switch on or off and put a branch check in my method. That seems like a kludge, though.

1
  • This is probably an easy question, but google didn't seem to have any ready answers. Google can be like a person who talks too much because sometimes the best thing is to stop listening and get things done. Commented Sep 29, 2011 at 20:10

5 Answers 5

39

Not sure if this is any use now but I found this answer, which seems cleaner to me.

From the MSDN Library - ComboBox.SelectionChangeCommitted Event

"SelectionChangeCommitted is raised only when the user changes the combo box selection. Do not use SelectedIndexChanged or SelectedValueChanged to capture user changes, because those events are also raised when the selection changes programmatically."

5
  • 4
    This is by far the simplest method. It does what the user wants without having to create & destroy event handlers. It also encourages better programming practices, where using a boolean to synchronize events in spite of other events is dangerous.
    – psyklopz
    Commented Mar 13, 2013 at 19:00
  • 4
    I also agree. This is simple and works effectively. The accepted answer did not work for me, and it does seem messy compared to this solution.
    – Cody
    Commented Feb 17, 2014 at 4:30
  • When it fires, the comboBox.Text has its old value.
    – Ahmad
    Commented Dec 19, 2015 at 6:17
  • @Ahmad what does that mean? Can't say I've had any problems with it myself.
    – user692942
    Commented Aug 30, 2017 at 9:17
  • 1
    This is nice. I searched for something like "SelectedIndexChanging" and the consensus seemed to be that it was not an option. Well, here it is. Commented Jul 15, 2018 at 20:49
39

I have done it a lot number of times. Solution1: Delete EventHandler from designer. Populate the combobox and then set EventHandler.

Combo1.SelectedIndexChanged += new EventHandler Combo1_SelectedIndexChanged;

But it will work only if you are populating the combobox once.If you are doing it for many number of times, then you may be in a mess.

Solution2: Its my preference and I use it regularily. Change your selection change event as:

private void cb1_SelectedIndexChanged(object sender, EventArgs e)
{
   ComboBox cb = (ComboBox)sender;
   if(!cb.Focused)
   {
      return;
   }
   // Here is your Code for selection change
}

So now the event will be fired only if its in focus. Hope you were looking for the same. Hope it Helps

3
  • 2
    Up vote for creativity. I've used this solution on other frameworks (Qt), but it ended up leading to some bad side effects. Was still the best solution in that case. Here, probably not. Commented Sep 30, 2011 at 13:22
  • Actually, the event must be triggered whether the component is not focused. Just invert the boolean condition... ;-)
    – cesarse
    Commented Apr 18, 2013 at 22:02
  • 1
    Greate solution! if you change the casting to Control its generic for any type of control.. Commented Jul 26, 2018 at 14:46
9

You can use both methods You proposed:

  1. use boolean variable
  2. detach event method, populate combobox, attach event method like this

    my_combo.SelectedIndexChanged -= my_Combo_SelectedIndexChanged;
    populateCombo();
    
    my_combo.SelectedIndexChanged += my_Combo_SelectedIndexChanged;
    

my_Combo_SelectedIndexChanged is the name of method you attached to the event.

4

I would use control.ContainsFocus instead of creating other bool. The caveat here is that you have to make sure the user has focus on that control. Either by key or mouse.

if(combo.ContainsFocus){ MyEventLogic();}
1
  • 1
    This is not a good idea. This is not bullet proof. What if you call for example a function from a timer which reloads the combobox while the combobox STILL has the focus from a previous click?
    – Elmue
    Commented Aug 22, 2018 at 23:53
2
  1. Solution: If you're populating combobox with static values only ones, just populate them and after subscribe to event from code. Do not use WinForms Designer to subscribe to it.
  2. If it's not possible during loading can:

    a) define a boolean variable bool loading, set it to true before you begin to populate combo with data, and in event handler check

    if(loading) return;

    b) Unsubsribe from event:

    If subscription was:

    comboBox.SelectedIndexChanged += delegate(...);

    Unsubscription before you begin load data is:

    comboBox.SelectedIndexChanged -= delegate(...);

As loading of data finished, subscribe again.

2
  • 1
    You seemed to understand the question since you sort of returned it back to me, but echoing the question is not exactly what I was looking for here. No up vote. Commented Sep 30, 2011 at 13:32
  • @micahhoover: honestly don't see any difference between mine answer and those ones I see in the list. I didn't ask you any question, but just provide with couple of solutions I think can be suitable to you. By the way, no prob, good luck.
    – Tigran
    Commented Sep 30, 2011 at 13:52

Not the answer you're looking for? Browse other questions tagged or ask your own question.