How can I prevent automatic selection in ComboBox with a drop-down list, except for exact matches?

I have a ComboBox, which is part of a detailed display related to a data grid containing rows from a database. There is no binding to ComboBox, I do it manually. ComboBox allows you to enter manually, as if it were a text field, but a drop-down menu was provided.

My problem is that if I manually entered the text in the field and the popup menu clicked, the ComboBox apparently wants to find a match. Also, it seems that the search is easy, so KG corresponds to KG/Day . I must avoid this and force an exact match.

But, in addition, I think that I need to manage the whole process myself, because to further complicate this issue, the drop-down element will read KG/Day - kilograms/day . The database field from which the data is extracted, however, only stores a part before the hyphen, therefore KG/Day .

So, I need to intercept the drop-down action so that I can do two things:

1) Perform your own search to find out if I have a special text or a β€œreal” match. As in the fact that it was originally selected from the drop-down list; in other words, I have KG/Day , not just KG .

2) Eliminate the automatic search behavior that ComboBox wants to do.

I tried to get the use of method handlers in the form, such as

ComboBox :: DropDown () and ComboBox :: DropDownClosed (),

but it seems like they still don't let me stop the main search / collation of the ComboBox.

I also tried to create a class of my own inherited from ComboBox, but I really do not know what to redefine, or how to do what I want in general, stopping what I am not doing.

So, I thank you for your advice.

EDIT: expand what I already tried ... In my inherited class, I tried to use the WndProc override. Based on some tips that I found in another forum, my goal was to intercept the ComboBox LB_FINDSTRING and replace it with LB_FINDSTRINGEXACT . The post suggested that the ComboBox does not match LB_FINDSTRING by default, which matches what I see, and that swapping LB_FINDSTRINGEXACT will cure the problem. The problem is that if I have a bad definition for LB_FINDSTRING , it was not received.

Here is my listing:

 [Flags] public enum ListBoxFlags { LB_ADDSTRING = 0x0180, LB_SETSEL = 0x0185, LB_GETSELITEMS = 0x0191, LB_GETSELCOUNT = 0x0190, LB_GETCURSEL = 0x0188, LB_SELECTSTRING = 0x018C, LB_SETCURSEL = 0x0186, LB_FINDSTRING = 0x018F, LB_FINDSTRINGEXACT = 0x01A2, LB_GETCOUNT = 0x018B, LB_GETSEL = 0x0187, LB_GETTEXT = 0x0189, LB_RESETCONTENT = 0x0184, LB_SETHORIZONTALEXTENT = 0x0194, LB_GETHORIZONTALEXTENT = 0x0193, LB_GETTOPINDEX = 0x018E, LB_SETTOPINDEX = 0x0197, LB_INSERTSTRING = 0x0181, LB_DELETESTRING = 0x0182, LB_GETITEMDATA = 0x0199 } 
+4
source share
1 answer

Made an example code that can help - you can use it as a guide.

The idea is to handle the TextChanged ComboBox event, and actually just change the ComboBox list items at this point. In the example below, the list will be modified to add the current text (most importantly, since this will not change the text when you click on the combo box) and any other items that match the search criteria.

I don't think you need code to reinitialize list items when focus is lost, but stayed there just in case.

  //contains a list of default items for the combobox items List<string> comboList = new List<string>(); public Form1() { InitializeComponent(); initComboList(); //initialize the defaults initCombobox(); //initialize the combobox list items } //fills the defaults for the combobox items private void initComboList() { comboList.Add("red"); comboList.Add("blue"); comboList.Add("green"); } //initializes the combobox items private void initCombobox() { comboBox1.Items.Clear(); foreach (string s in comboList) comboBox1.Items.Add(s); } //occurs when the text changes in the combobox private void comboBox1_TextChanged(object sender, EventArgs e) { string curtext = comboBox1.Text; insertIntoComboBox(curtext); //insert the current text into combobox comboBox1.Select(curtext.Length, 0); //if you don't do this, the cursor goes back to index 0 :-( } //called whenever is desired to insert the current text into the combobox items private void insertIntoComboBox(string curtext) { comboBox1.Items.Clear(); //only add the current text if it not already in the list of defaults and not empty string if (comboList.Contains(curtext) == false && curtext.Length > 0) comboBox1.Items.Add(curtext); foreach (string s in comboList) comboBox1.Items.Add(s); } //called whenever combobox loses focus private void comboBox1_Leave(object sender, EventArgs e) { initCombobox(); } 
0
source

All Articles