简体   繁体   中英

How to prevent TextChanged event when I select an item in combobox?

I have a TextChanged event on my ComboBox like;

private void comboBox1_TextChanged(object sender, EventArgs e)
{
     foreach (var item in comboBox1.Items.Cast<string>().ToList())
     {
         comboBox1.Items.Remove(item);
     }

     foreach (string item in InputBox.AutoCompleteCustomSource.Cast<string>().Where(s => s.Contains(comboBox1.Text)).ToList())
     {
         comboBox1.Items.Add(item);
     }
}

As an explanation, when I change the text of combobox, I want to get string values contains in AutoCompleteCustomSource on InputBox (which is TextBox ).

It works fine when I search them but when I select the item, obviously TextChanged event triggered again and Text property of Combobox will reset.

How to solve this?

If I understood correctly then i think you want to hide the TextChange event of the combobox. If it is then you can create a custom control inherited by ComboBox and override the TextChange event.

public partial class MyCombo : ComboBox
{
    public MyCombo()
    {
        InitializeComponent();
    }
    bool bFalse = false;
    protected override void OnTextChanged(EventArgs e)
    {
        //Here you can handle the TextChange event if want to suppress it 
        //just place the base.OnTextChanged(e); line inside the condition
        if (!bFalse)
            base.OnTextChanged(e);
    }
    protected override void OnSelectionChangeCommitted(EventArgs e)
    {
        bFalse = true;
        base.OnSelectionChangeCommitted(e);
    }
    protected override void OnTextUpdate(EventArgs e)
    {
        base.OnTextUpdate(e);
        bFalse = false; //this event will be fire when user types anything. but, not when user selects item from the list.
    }
}

EDITED: Another simple soution is use TextUpdate event instead of TextChange and keep your combobox as it is without creating another custom control.

private void myCombo1_TextUpdate(object sender, EventArgs e)
{
    foreach (var item in myCombo1.Items.Cast<string>().ToList())
    {
        myCombo1.Items.Remove(item);
    }

    foreach (string item in myCombo1.AutoCompleteCustomSource.Cast<string>().Where(s => s.Contains(myCombo1.Text)).ToList())
    {
        myCombo1.Items.Add(item);
    }
}

TextUpdate event will call only when user types anything in combobox. But, not when user selects item from the drop down list. So, this will not resent the added items.

You can also change the where condition if you wish to return all matched items in both cases(Upper and Lower). Suppose you have a two items in the list 1. Microsoft Sql Server, 2. microsoft office then what would be the result if i type microsoft only.

Where(s => s.ToLower().Contains(comboBox1.Text.ToLower()))

Sample Code

在此输入图像描述

As @Sayse already said:

Add a boolean:

private bool codeCalled = new bool();

In your textChanged:

if(codeCalled == true)
{
    codeCalled = false;   
    return;
}
else
{
     codeCalled = true;
    //your foreachcode here        
}

That should do the trick.

Tested and is working.

Also tested and working, also not elegant:

private void textBox_TextChanged(object sender, EventArgs e)
{
    textBox.TextChanged -= textBox_TextChanged;

    //yourcode

    textBox.TextChanged += textBox_TextChanged;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM