5

How do I create an Auto-complete ComboBox or TextBox that filters text based on a string?

For example: if I type an "a" in a TextBox, I only get to see all strings containing an "a".

Emond
  • 50,210
  • 11
  • 84
  • 115
jozi
  • 2,833
  • 6
  • 28
  • 41

6 Answers6

8

If you mean show suggestions then it's a simple matter of changing a property when you have the TextBox selected in your IDE of choice:

The options shown in the picture allow you to change the rules for autocompleting text in the text box as well as the source for the suggestions. (Visual Studio 2010)

Properties

You can go to the following link to learn more about the TextBox control.

MSDN Text Box Control

Jamie Keeling
  • 9,806
  • 17
  • 65
  • 102
3

Windows Forms's autocomplete implementation uses Shell's autocomplete object, which can only do a "BeginWith" match until Windows Vista. If you can demand your users to upgrade to Windows Vista, you can use IAutoComplete2::SetOptions to specify ACO_NOPREFIXFILTERING. Otherwise I am afraid you need to write your own.

Sheng Jiang 蒋晟
  • 15,125
  • 2
  • 28
  • 46
  • How is this done when using the default TextBox and ComboBox implementations? – test Mar 17 '14 at 17:41
  • You can't. The Windows Forms implementation is not customizable for this task. – Sheng Jiang 蒋晟 Mar 18 '14 at 05:44
  • Thanks for confirming, I kinda figured that based on your implementation that you linked. Can you tell me why the implementation you made doesn't properly handle up and down keys? If I use the ACO_NOPREFIXFILTERING flag with your implementation the up and down keys will select the last and first item, respectively, and then close the auto complete window. No selection highlight is shown. – test Mar 18 '14 at 15:56
  • This probably has something to do with resetting the candidate list. If you just want a regular autocomplete (no candidate list refresh when you are typing) you can comment out the code in the TextChanged event. – Sheng Jiang 蒋晟 Mar 18 '14 at 16:55
1

Here is how I auto-complete for a specific value in a comboDropDown box.

    void comboBox_Leave(object sender, EventArgs e)
    {
       ComboBox cbo = (sender as ComboBox);
        if (cbo.Text.Length > 0)
        {
            Int32 rowIndex = cbo.FindString(cbo.Text.Trim());
            if (rowIndex != -1)
            {
                cbo.SelectedIndex = rowIndex;
            }
            else
            {
                cbo.SelectedIndex = -1;
            }
        }
        else
        {
            cbo.SelectedIndex = -1;
        }

    }
Gary Kindel
  • 17,071
  • 7
  • 49
  • 66
0

I know this is an old topic but i tried so hard to find a solution for c# autocomplete filtering too and couldn't find any so i came up with my own simple and easy way so i'll just share it for those who may think it's useful and wanna use in their projects. It does not use the control's autocomplete features. What it does just simply get the text entered from the combobox, search it in the source then display only the matching ones from the source as the combobox' new source. I implemented it in the combobox' KeyUp event.

Let's say (actually this is what i do for almost all the cases when i want autocompleting) we have a globally assigned DataTable called dt_source to be the combobox' source and it has two columns: id(int) and name(string).

DataTable dt_source = new DataTable("table");
dt_source.Columns.Add("id", typeof(int));
dt_source.Columns.Add("name", typeof(string));

And this is what my KeyUp method looks like:

private void cmb_box_KeyUp(object sender, KeyEventArgs e)
{
  string srch = cmb_box.Text;
  string srch_str = "ABackCDeleteEFGHIJKLMNOPQRSpaceTUVWXYZD1D2D3D4D5D6D7D8D9D0"; 
  if (srch_str.IndexOf(e.KeyCode.ToString()) >= 0)
  {
    cmb_box.DisplayMember = "name"; // we want name list in the datatable to be shown
    cmb_box.ValueMember = "id"; // we want id field in the datatable to be the value
    DataView dv_source = new DataView(dt_source);  // make a DataView from DataTable so ...
    dv_source.RowFilter = "name LIKE '%"+ srch +"%'"; // ... we can filter it
    cmb_box.DataSource = dv_source; // append this DataView as a new source to the combobox         
    /* The 3 lines below is the tricky part. If you repopulate a combobox, the first
       item in it will be automatically selected so let's unselect it*/
    cmb_box.SelectedIndex = -1; // unselection
    /* Again when a combobox repopulated the text region will be reset but we have the
       srch variable to rewrite what's written before */
    cmb_box.Text = srch;
    /* And since we're rewriting the text region let's make the cursor appear at the
       end of the text - assuming 100 chars is enough*/
    cmb_box.Select(100,0);
    cmb_box.DroppedDown = true; // Showing the dropdownlist
   }
}
Batu.Khan
  • 3,060
  • 2
  • 19
  • 26
0

This filters results based on user input. Optimizing for large lists, populating your own data and error handling left out for you to complete:

public partial class Form1 : Form
    {

        List<String> data;
        ListView lst = new ListView();
        TextBox txt = new TextBox();

        public Form1()
        {
            InitializeComponent();
            data = new List<string>("Lorem ipsum dolor sit amet consectetur adipiscing elit Suspendisse vel".Split());
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.Controls.Add(txt);
            lst.Top = 20;
            txt.TextChanged += new EventHandler(txt_TextChanged);
            lst.View = View.List;
            this.Controls.Add(lst);
            list_items("");
        }

        void txt_TextChanged(object sender, EventArgs e)
        {
            list_items(txt.Text);
        }

        void list_items(string filter)
        {
            lst.Items.Clear();
            List<string> results = (from d in data where d.Contains(filter) select d).ToList();
            foreach (string s in results)
            {
                lst.Items.Add(s);
            }
        }
    }

To get the combobox to auto complete, set the AutoCompleteSource and AutoCompleteMode properties:

cbo.AutoCompleteSource = AutoCompleteSource.ListItems;
cbo.AutoCompleteMode = AutoCompleteMode.SuggestAppend;

The ListItems source tells the combo to use it's items collection as the auto complete source.

invert
  • 2,016
  • 14
  • 20
-2

I think your best bet is to override the OnKeyDown(KeyEventArgs e) event, and use the value to filter the ComboBox.AutoCompleteCustomSource. Then as noted above, change the AutoCompleteSource to AutoCompleteSource.ListItems.

bryanjonker
  • 3,386
  • 3
  • 24
  • 37
  • Handling `OnKeyDown` is generally considered your worst bet. Among other things, it will fail to handle input pasted into the Edit control (e.g. right click -> Paste). – IInspectable Feb 16 '15 at 21:26
  • for combobox ref this http://stackoverflow.com/questions/11780558/c-sharp-winforms-combobox-dynamic-autocomplete/41461062#41461062 – Devanathan.S Jan 04 '17 at 10:06