我有一个组合框,它是与包含数据库中的行的数据网格相关的详细信息显示的一部分。不存在对组合框的绑定,我正在手动执行此操作。组合框允许手动输入,就像它是一个文本字段一样,同时仍然提供下拉选项。
我的问题是,如果我在字段中手动输入文本,并且单击下拉菜单,则组合框显然想要寻找匹配项。另外,看起来搜索很简单,因此KG匹配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,这符合我所看到的效果,并且替换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
}
Run Code Online (Sandbox Code Playgroud)
制作了一些可能有帮助的示例代码 - 您可以将其用作指南。
这个想法是处理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();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5777 次 |
| 最近记录: |