Search code examples
c#winformssortingcomboboxautocomplete

C# WinForms ComboBox: AutoComplete does not sort descending


In a WinForms dataviewer project I've made a ComboBox to select a filter value. The list items come from of a database query. They are sorted descending. The ComboBox uses AutoCompleteMode.Append. Although the dropdown list is sorted descending, the AutoComplete always suggests the lowest matching value instead of the highest. This happens even if I explicitly populate the AutoCompleteCustomSource with descending data.

Does anyone know how to make the AutoComplete suggesting the highest matching value?

The ComboBox looks like this after typing "010":
Filter_ComboBox

This is a part of the dropdown list:
...
012-0020-00
010-0070-00
010-0069-00
010-0068-00
008-1018-00
...

Why this matters:
I will use this filter for various string data containing numbers, like parts codes, document codes, project codes etc. Newer entries have higher numbers. And the newest entries are queried most often. In the above example, 010-0070-00 ist the newest part code of the 010 group. Therefore I expect the AutoComplete to show 010-0070-00 after I have typed 010.

This project replaces an MS Access front end. An Access ComboBox suggests the highest value if the list is sorted descending resp. the lowest value if sorted ascending. But Access ComboBoxes are not WinForms controls.

Any suggestions are welcome.


Solution

  • Example using a ToolStripDropDown:

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
    
        String[] data = "012-0020-00,010-0070-00,010-0069-00,010-0068-00,008-1018-00".Split(',');
        ComboBox combo = new ComboBox();
        //ToolStripDropDownMenu menu = new ToolStripDropDownMenu(); // has image/icon border
        ToolStripDropDown menu = new ToolStripDropDown(); // plain menu, no image/icon border
        menu.AutoClose = false;
        bool isAdjusting = false;
        combo.LostFocus += delegate {
            if (!isAdjusting)
                menu.Close();
        };
        menu.ItemClicked += (o, e) => {
            isAdjusting = true;
            combo.Text = e.ClickedItem.Text;
            menu.Close();
            isAdjusting = false;
        };
    
        combo.TextChanged += delegate {
            if (isAdjusting)
                return;
            isAdjusting = true;
            String prefix = combo.Text;
            menu.SuspendLayout();
            for (int i = menu.Items.Count - 1; i >= 0; i--) {
                var item = menu.Items[i];
                menu.Items.RemoveAt(i);
                item.Dispose();
            }
            foreach (String part in data) {
                if (part.StartsWith(prefix))
                    menu.Items.Add(new ToolStripMenuItem(part));
            }
            menu.ResumeLayout();
            menu.Show(combo, 0, combo.Height);
            combo.Focus();
            combo.SelectionStart = prefix.Length;
            isAdjusting = false;
        };
    
        Form f7 = new Form();
        f7.Controls.Add(combo);
        Application.Run(f7);