Justin
Justin

Reputation: 700

Change the ComboBox's text field when an item is selected from the drop down list?

I have a ComboBox on a form. The DropDownStyle property of the ComboBox is set to DropDown, so that the user can select an item from the drop down list or type in some text manually.

When the user selects an item from the drop down list, I'd like to make some changes to the item's text before it appears in the ComboBox's text field. To use a very simplified example, let's say the drop down list contains items that consist of an ID and a description, like so:

101 Cat
102 Dog
103 Bird

When one of these items is selected, I'd like only the description to appear in the ComboBox's text field. So when "102 Dog" is selected, the string "Dog" should be displayed in the text field, ready to be edited by the user, and the items in the drop down list should be unchanged.

I thought I could just listen to, say, the SelectionChangeCommitted event of the ComboBox, and set the Text property of the ComboBox to whatever I like. But if I do this, the changes I make to Text are ignored, and the entire string ("102 Dog") is still displayed in the ComboBox.

So then I thought I should also update the SelectedIndex field to -1, to indicate to the ComboBox that the Text I'm setting is not an item in the drop down list. But this just clears the text field completely, regardless of what I change the Text property to.

So then I figured that SelectionChangedCommitted is the wrong event to be using, as it appears to fire too soon for my purposes (the Text property seems to only be updated with my selection after the SelectionChangeCommitted event handler has completed). But all other ComboBox events also fail to work, including SelectedIndexChanged and DropDownClosed.

I thought this would be pretty trivial to acheive. There's got to be a simple way to do this, and I'm sure I'm missing something obvious... any ideas?

Upvotes: 3

Views: 8566

Answers (3)

The Lemon
The Lemon

Reputation: 1391

The above solutions all work great, but fail when you want to use the style 'DropDownList' - which is a requirement for me, so I overengineered something else

Note: the below code has the same class reflect itself in both string formats. You can do it with a dictionary lookup and populate with .keys and .values instead, either way works.

EventCode

private bool activateCombobox = false;
private void myComboBox_DropDown(object sender, EventArgs e)
{
    Foo.IsDroppedDown = true;
        myComboBox.Items.Clear();
        myComboBox.Items.AddRange(fooItems);
    Foo.IsDroppedDown = false;
    activateCombobox = true;
}

private void myComboBox_SelectedValueChanged(object sender, EventArgs e)
{
    if (activateCombobox)
    {
        activateCombobox = false;
        var selectedItem = myComboBox.SelectedItem;
        myComboBox.Items.Clear();
        myComboBox.Items.AddRange(fooItems);
        myComboBox.SelectedItem = selectedItem;
    }
        
}

and then our class code (change it to your classes ofc, this is just an example)

private Foo[] fooItems = new Foo[] { new Foo(1), new Foo(2), new Foo(3) };
private class Foo
{
    public int index = 0;
    public Foo() { }
    public Foo(int index) { this.index = index; }
    public string dropdownFoo { get { return $"Foo{index}"; } }
    public string displayFoo { get { return $"Bar{index}"; } }
    public override string ToString()
    {
        if (IsDroppedDown)
            return dropdownFoo;
        return displayFoo;
    }
    public static bool IsDroppedDown = false;
}

Upvotes: 0

Benoit Drapeau
Benoit Drapeau

Reputation: 624

Just to clarify, are you displaing "101 Cat", "102 Dog", etc. when the user dropdown the combo and displaying them when selected? Is 101 the key for the "Cat", 102 the key for the "Dog", and so on? If so, why are you displaying them and not only displaying the text of each item (if this is your requirement, apologize my answer). For what I understand, I'll configure the combobox valuemember to the property that returns you the 101, 102, etc. and the displaymember to the property that returns you the text of each items. This way, you'll already get what you want, i.e. displaying the "Cat", "Dog" and "Bird" text. Also, you can attach an event to the TextChanged event of the combo if you want furter processing.

Upvotes: 0

LarsTech
LarsTech

Reputation: 81610

You can try this:

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
  if (comboBox1.SelectedIndex > -1)
  {
    string value = comboBox1.Items[comboBox1.SelectedIndex].ToString().Substring(4);
    this.BeginInvoke((MethodInvoker)delegate { this.comboBox1.Text = value; });
  }
}

Upvotes: 4

Related Questions