4

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

我的问题是,如果我在字段中手动输入了文本,并且单击了下拉菜单,则 ComboBox 显然想要寻找匹配项。此外,搜索似乎很简单,因此KGmatch KG/Day。我必须避免这种情况并强制进行精确匹配。

但更进一步,我认为我需要能够自己管理整个过程,因为更复杂的是,下拉项实际上会显示为KG/Day - kilograms/day. 但是,从中获取数据的数据库字段仅存储连字符之前的部分,因此KG/Day.

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

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

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

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

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

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

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

因此,我感谢您的建议。

编辑:扩展我已经尝试过的内容......在我继承的类中,我试图使用WndProc覆盖。根据我在另一个论坛上找到的一些建议,我的目标是拦截 ComboBox 消息LB_FINDSTRING并将其替换为LB_FINDSTRINGEXACT. 该帖子建议 ComboBox 默认为LB_FiNDSTRING,这符合我所看到的,并且 subbingLB_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
}
4

1 回答 1

0

制作了一些可能有帮助的示例代码 - 您可以用作指南。

这个想法是处理 的TextChanged事件ComboBox,实际上只是ComboBox list items在那时修改 。下面的示例将修改列表以添加当前文本(最重要的是,当您单击组合框时这不会更改文本)和任何其他符合搜索条件的项目。

我认为您不需要在失去焦点时重新初始化列表项的代码,但以防万一。

    //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'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();
    }
于 2013-05-14T14:56:37.490 回答