Search code examples
c#winformscomboboxautocompletefuzzy-search

How to Get Autocomplete to not just search the starts with but uses contains, for eg contains "Doors"


With Autocomplete you can search starts with and this works really well. However the strings that are searched on do not always start with the string you would like to find. For example from a dictionary that I have added that contians the strings...

Doors opening elements
exterior doors
interior doors
sliding doors

only Doors opening elements, is returned from an auto-complete search.

Here is the code I use to populate autocomplete...

        Dictionary<string, string> items = KN_File.CreateDictFromTextFile(filePath);
        List<string> treeBasedList = new List<string>();

        foreach (KeyValuePair<string, string> kvp in items)
        {
            treeBasedList.Add(kvp.Value + "," + kvp.Key);
        }

        AutoCompleteStringCollection AutoCompleteList = new AutoCompleteStringCollection();
        AutoCompleteList.AddRange(treeBasedList.ToArray());
        comboBx.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
        comboBx.AutoCompleteSource = AutoCompleteSource.CustomSource;
        comboBx.AutoCompleteCustomSource = AutoCompleteList;

Solution

  • Here is a workaround that maybe you can refer to.

    private void Form1_Load(object sender, EventArgs e)
    {
        listOriginal.Add("Doors opening elements");
        listOriginal.Add("exterior doors");
        listOriginal.Add("interior doors");
        listOriginal.Add("sliding doors");
    
        this.comboBx.Items.AddRange(listOriginal.ToArray());
    }
    
    // Bind default keywords
    List<string> listOriginal = new List<string>();
    // save new keywords
    List<string> listNew = new List<string>();
    
    private void comboBx_TextUpdate(object sender, EventArgs e)
    {
        //clear combobox
        this.comboBx.Items.Clear();
        //clear listNew
        listNew.Clear();
        foreach (var item in listOriginal)
        {
            // call ToLower() .. not case sensitive
            if (item.ToLower().Contains(this.comboBx.Text))
            {
                //add to ListNew
                listNew.Add(item);
            }
        }
        this.comboBx.Items.AddRange(listNew.ToArray());
        this.comboBx.SelectionStart = this.comboBx.Text.Length;
        Cursor = Cursors.Default;
        // Automatically pop up drop-down
        this.comboBx.DroppedDown = true;
    }
    

    Test result,

    enter image description here