locked
Autocomplete combobox match any part of string not only beginning string. RRS feed

  • 问题

  • I have a combobox, and it contains items: 123 abc, 12 ab, abc 123, def, ghm 123

    I want when i write "123" into combobox, then droppeddown list show: 123 abc

                                                                                                                         abc 123

                                                                                                                                                       ghm 123

    Please helpme!

    Thanks!



    2012年6月24日 4:39

答案

  • In this case, autocompletemode will just not do. Its code is not meant for something like it.

    You will have to do your own code, to do the filtering on each letter press.

    So I would suggest not to use autocompletemode, and get all the data (names) into dataTable. When user presses some button ("1" for example), you start with your filtering, by creating new Datatable (leave the main one untached - so you can return back to all data when clearing comboBox by backspace), with Copy() method - to create a full copy of original one, and use Select method to do the filteing.

    This should look something like by using % simbol on both sides of a string - to filter inbetween - this is what you want!

    DataTable AllNames = new DataTable();
    //fill it up and leave it untouched!
    
    //to filter comboBox with names that contains pressed characters do in 
    private void comboBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
        string name = string.Format("{0}{1}", comboBox1.Text, e.KeyChar.ToString()); //join previous text and new pressed char
        DataRow[] rows = table.Select(string.Format("FieldName LIKE '%{0}%'", name));
       DataTable filteredTable = AllNames.Clone();
       foreach(DataRow r in rows)
           filteredTable.ImportRow(r);
       comboBox1.DataSource = null;
       comboBox1.DataSource = filteredTable.DefaultView;
       comboBox1.DisplayMember = "FieldName";
    }

    Hope it helps,

    bye


    Mitja

    2012年6月24日 8:06

全部回复

  • In this case, autocompletemode will just not do. Its code is not meant for something like it.

    You will have to do your own code, to do the filtering on each letter press.

    So I would suggest not to use autocompletemode, and get all the data (names) into dataTable. When user presses some button ("1" for example), you start with your filtering, by creating new Datatable (leave the main one untached - so you can return back to all data when clearing comboBox by backspace), with Copy() method - to create a full copy of original one, and use Select method to do the filteing.

    This should look something like by using % simbol on both sides of a string - to filter inbetween - this is what you want!

    DataTable AllNames = new DataTable();
    //fill it up and leave it untouched!
    
    //to filter comboBox with names that contains pressed characters do in 
    private void comboBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
        string name = string.Format("{0}{1}", comboBox1.Text, e.KeyChar.ToString()); //join previous text and new pressed char
        DataRow[] rows = table.Select(string.Format("FieldName LIKE '%{0}%'", name));
       DataTable filteredTable = AllNames.Clone();
       foreach(DataRow r in rows)
           filteredTable.ImportRow(r);
       comboBox1.DataSource = null;
       comboBox1.DataSource = filteredTable.DefaultView;
       comboBox1.DisplayMember = "FieldName";
    }

    Hope it helps,

    bye


    Mitja

    2012年6月24日 8:06
  • I agree with Mitja.  Autocomplete is not appropriate.  Look at the name, auto-complete.  It finishes typing a word for the user.  You need to setup your own custom drop list dynamically, per Mitja's suggestion.

    Rudy   =8^D


    Mark the best replies as answers. "Fooling computers since 1971."

    http://thesharpercoder.blogspot.com/

    2012年6月24日 10:56
  • Hi. This code helped me alot. But I'm having this issue that one of the results comes up in the combobox itself, and not staying in the dropdown. 

    If my table contains "One", "Two" and "Three" for exampel, and I type "o", "One" adds to the "o" and it looks like this "oOne" and I cant type anymore then one letter.

    I have tried to experiment with the code with no luck. I'm a newbie too :/

    Also I think I understand mostly of the code, but I cant see where it decides to add the tablecontent to the letter.

    Might add that when I press enter, it clears the box.

    Best regards


    2013年9月24日 16:09
  • 
        string name = string.Format("{0}{1}", comboBox1.Text, e.KeyChar.ToString()); //join previous text and new pressed char
        DataRow[] rows = table.Select(string.Format("FieldName LIKE '%{0}%'", name));
       
            what is that table meant for ??
    2017年6月16日 8:09
  • Use this code : 

    public partial class MyComboBox : ComboBox
        {
    
            private IList<object> collectionList = null;
    
            public MyComboBox()
            {
                InitializeComponent();
                collectionList = new List<object>();
            }
            public MyComboBox(IContainer container)
            {
                container.Add(this);
                InitializeComponent();
            }
    
            protected override void OnTextUpdate(EventArgs e)
            {
                IList<object> Values = collectionList
                    .Where(x => x.ToString().ToLower().Contains(Text.ToLower()))
                    .ToList<object>();
    
                this.Items.Clear();
                if (this.Text != string.Empty)
                    this.Items.AddRange(Values.ToArray());
                else
                    this.Items.AddRange(collectionList.ToArray());
    
                this.SelectionStart = this.Text.Length;
                this.DroppedDown = true;
            }
    
            protected override void OnTextChanged(EventArgs e)
            {
                if(this.Text == string.Empty)
                {
                    this.Items.Clear();
                    this.Items.AddRange(collectionList.ToArray());
                }
            }
    
            protected override void OnCreateControl()
            {
                base.OnCreateControl();
                collectionList = this.Items.OfType<object>().ToList();
            }
        }
    



    2017年10月21日 6:40
  • Hi, sorry to bring up a really old post. But is there any way to replicate this in Excel?

    Thanks!

    2018年1月25日 4:40
  • but why the mouse cursor disappear when I enter a text to search ?!! 
    2018年7月17日 13:29
  • What is Table.Select

    2018年9月10日 4:58
  • This doesn't work at all, not sure why this was an accepted answer if this code wasn't even tested. First of all, as you type in to the combo box, it doesn't clear out what is in the field, the way an autocomplete acts. The combobox automatically selects the first matching item unwantedly, which unwantedly appends to what you're typing, which means this function doesn't work for anything more than a single character. Second of all, you're not handling backspace keys in case you make a mistake, which are entered at a parameter. Thirdly, you don't take care of the condition of a field when there are no texts that has been entered, if it's blank you're supposed to return the entire list. It's a broken answer.
    2019年7月10日 0:21
  • I'm getting this error message: 

    An unhandled exception of type 'System.Data.SyntaxErrorException' occurred in System.Data.dll
    Additional information: Syntax error: Missing operand after 'diagtext' operator.

    My Code:

    DataTable AllNames = new DataTable();
            private void Cward_combox_KeyPress(object sender, KeyPressEventArgs e)
            {
                string name = string.Format("{0}{1}", Cward_combox.Text, e.KeyChar.ToString()); 
                DataRow[] rows = table.Select(string.Format("select diagtext from hencdiag where diagtext LIKE '%{0}%'", name));
                DataTable filteredTable = AllNames.Clone();
                foreach (DataRow r in rows)
                    filteredTable.ImportRow(r);
                Cward_combox.DataSource = null;
                Cward_combox.DataSource = filteredTable.DefaultView;
                Cward_combox.DisplayMember = "diagtext";
            }


    2019年10月25日 16:12