0

I have 15 comboBox'es, and I do not want to create an event handler for each. How do I make just one procedure and tie all Combobox'es to it?

private void cbSlots0_SelectedIndexChanged(object sender, EventArgs e)
{
    var item = ConfigClass.Slots["0"][cbSlots0.SelectedIndex];
    ConfigClass.Slots["0"].Insert(0, item);
    ConfigClass.Slots["0"].RemoveAt(cbSlots0.SelectedIndex + 1);
}

private void cbSlots1_SelectedIndexChanged(object sender, EventArgs e)
{
    var item = ConfigClass.Slots["1"][cbSlots1.SelectedIndex];
    ConfigClass.Slots["1"].Insert(1, item);
    ConfigClass.Slots["1"].RemoveAt(cbSlots1.SelectedIndex + 1);
}

Correct answer:

var cb = ((ComboBox)sender);
            var tag = int.Parse(cb.Tag.ToString());
            var item = ConfigClass.Slots[tag.ToString()][cb.SelectedIndex];
            ConfigClass.Slots[tag.ToString()].Insert(tag, item);
            ConfigClass.Slots[tag.ToString()].RemoveAt(cb.SelectedIndex + 1);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mediator
  • 14,951
  • 35
  • 113
  • 191
  • possible duplicate of [Set up single event handler for multiple buttons in .NET?](http://stackoverflow.com/questions/4157851/set-up-single-event-handler-for-multiple-buttons-in-net), [c# reuse event handler good practice](http://stackoverflow.com/questions/641365/c-reuse-event-handler-good-practice) – Cody Gray - on strike Jul 17 '11 at 15:37

4 Answers4

3

You can give each ComboBox a distinct Tag, which contains the number of the entry in the ConfigClass, and then use that like so:

private void cbSlots0_SelectedIndexChanged(object sender, EventArgs e)
{
    int tag = (int)((ComboBox)sender).Tag;
    var item = ConfigClass.Slots[tag.ToString()][cbSlots0.SelectedIndex];
    ConfigClass.Slots[tag.ToString()].Insert(tag, item);
    ConfigClass.Slots[tag.ToString()].RemoveAt(cbSlots0.SelectedIndex + 1);
}

The tag can contain any data you want, so if you need something more complex stored in there, that's also a possibility.

Sebastian Paaske Tørholm
  • 49,493
  • 11
  • 100
  • 118
1

I would recommend one event handler for all ComboBoxes. Afterwards, within your event handler, use the sender reference to decide which slot to use:

private void allComboBoxesSelectedIndesChanged(object sender, EventArgs e)
{
    int index = 0; // Or string as you have shown in your example.

    if (sender == cbSlots0)
        index = 0;
    else if (sender == cbSlots1)       
        index = 1;
    /// And so on for any other comboBox

    var item = ConfigClass.Slots[index][((ComboBox) sender).SelectedIndex];
    ConfigClass.Slots[index].Insert(index, item);
    ConfigClass.Slots[index].RemoveAt(((ComboBox) sender).SelectedIndex +1);
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Pilgerstorfer Franz
  • 8,303
  • 3
  • 41
  • 54
  • -1: That big if/else if/... structure is going to be a pain to maintain. Would be better off with separate event handlers passing an index to a shared common method. (But, in this case, use of `Control.Tag` is an effective approach.) – Richard Jul 17 '11 at 16:06
0

This is relatively simple. You create a single SelectedIndexChanged event handler method, and then wire that up to all of the combo box controls.

The way you distinguish between the controls inside of the method at run-time is by checking the value of the sender parameter. You'll have to cast it to a ComboBox control, but that's safe because you know that you didn't wire up any non-combobox controls to that event handler. Then you'll be able to access all the properties of the combobox that raised the event you're handling.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
0

Tie each item in your markup to the same SelectedIndexChangedEvent and cast the sender as your item. So, in your code, look for all of the unique event names (ie. cbSlots0_SelectedIndexChanged, cbSlots1_SelectedIndexChanged, etc) and rename them to the single event name (eg. cbSlotsSelectedIndexChanged).

I think this is right. Verify.

CODE:

private void cbSlotsSelectedIndexChanged(object sender, EventArgs e)
{
    ComboBox cBox = (ComboBox) sender;
    int tag = (int)cBox.Tag;
    var item = ConfigClass.Slots[tag.ToString()][cBox.SelectedIndex];
    ConfigClass.Slots[tag.ToString()].Insert(tag, item);
    ConfigClass.Slots[tag.ToString()].RemoveAt(item.SelectedIndex + 1);
}

UPDATE: I revised my post as requested

private void cbSlotsSelectedIndexChanged(object sender, EventArgs e)
{
    var cb = ((ComboBox)sender);
    var tag = int.Parse(cb.Tag.ToString());
    var item = ConfigClass.Slots[tag.ToString()][cb.SelectedIndex];
    ConfigClass.Slots[tag.ToString()].Insert(tag, item);
    ConfigClass.Slots[tag.ToString()].RemoveAt(cb.SelectedIndex + 1);
}
Alban
  • 704
  • 1
  • 6
  • 11
  • Good, but please edit post. var cb = ((ComboBox)sender); var tag = int.Parse(cb.Tag.ToString()); var item = ConfigClass.Slots[tag.ToString()][cb.SelectedIndex]; ConfigClass.Slots[tag.ToString()].Insert(tag, item); ConfigClass.Slots[tag.ToString()].RemoveAt(cb.SelectedIndex + 1); – Mediator Jul 17 '11 at 15:50