除完全匹配外,如何在下拉列表中阻止ComboBox中的自动选择?

我有一个ComboBox,它是与包含数据库行的数据网格相关的详细信息显示的一部分。 没有绑定到ComboBox,我正在手动执行此操作。 ComboBox允许手动输入,就像它是文本字段一样,同时仍然提供下拉选项。

我的问题是,如果我在字段中手动输入文本,并且单击下拉列表,则ComboBox显然想要找出匹配项。 此外,看起来搜索很简单,因此KG匹配KG/Day 。 我必须避免这种情况并强制完全匹配。

但进一步说,我认为我需要能够自己管理整个过程,因为为了使问题进一步复杂化,下拉项目实际上将读取KG/Day - kilograms/day 。 但是,从中获取数据的数据库字段仅存储连字符之前的部分,因此KG/Day

所以,我需要以一种允许我做两件事的方式拦截下拉动作:

1)执行我自己的搜索,以查找我是否有特别文本或“真实”匹配。 因为它最初是从下拉列表中选择的; 换句话说,我有KG/Day而不仅仅是KG

2)消除ComboBox想要做的自动搜索行为。

我尝试使用Form中的方法处理程序来处理这些事情,例如

ComboBox :: DropDown()和ComboBox :: DropDownClosed(),

但似乎这些仍然不允许我停止基本的ComboBox搜索/匹配。

我也尝试创建一个inheritance自ComboBox的我自己的类,但我真的不知道要覆盖什么,或者一般来说如何获得我想要的东西,停止我不想要的东西。

所以,有了这个,我感谢你的建议。

编辑:扩展我已经尝试过的…在我inheritance的类中,我试图使用WndProc覆盖。 基于我在另一个论坛中发现的一些建议,我的目标是拦截ComboBox消息LB_FINDSTRING并将其替换为LB_FINDSTRINGEXACT 。 该post暗示ComboBox默认为LB_FiNDSTRING ,这符合我所看到的,并且LB_FINDSTRINGEXACT可以解决问题。 麻烦的是,除非我得到LB_FINDSTRING的错误定义,否则从未收到过。

这是我的枚举:

 [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 } 

制作了一些可能有用的示例代码 – 您可以将其用作指南。

我们的想法是处理ComboBoxTextChanged事件,并且实际上只是修改了那时的ComboBox list items 。 下面的示例将修改列表以添加当前文本(最重要的是,因为这不会在单击combobox时更改文本)以及满足搜索条件的任何其他项目。

我不认为你需要代码在焦点丢失时重新初始化列表项,但为了以防万一而留在那里。

  //contains a list of default items for the combobox items List comboList = new List(); 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's 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(); }