简体   繁体   English

组合框上的自动完成限制

[英]Restricted autocompletion on combobox

I have a combobox that I don't want users adding new data too, but I also want to let them type in the title of the object they want to select. 我有一个组合框,我也不想让用户也添加新数据,但我也想让他们键入要选择的对象的标题。

Currently I am using this code: 目前,我正在使用此代码:

    protected virtual void comboBoxAutoComplete_KeyPress(object sender, KeyPressEventArgs e) {
        if (Char.IsControl(e.KeyChar)) {
            //let it go if it's a control char such as escape, tab, backspace, enter...
            return;
        }
        ComboBox box = ((ComboBox)sender);

        //must get the selected portion only. Otherwise, we append the e.KeyChar to the AutoSuggested value (i.e. we'd never get anywhere)
        string nonSelected = box.Text.Substring(0, box.Text.Length - box.SelectionLength);

        string text = nonSelected + e.KeyChar;
        bool matched = false;
        for (int i = 0; i < box.Items.Count; i++) {
            if (((DataRowView)box.Items[i])[box.DisplayMember].ToString().StartsWith(text, true, null)) {
                //box.SelectedItem = box.Items[i];
                matched = true;
                break;
            }
        }

        //toggle the matched bool because if we set handled to true, it precent's input, and we don't want to prevent
        //input if it's matched.
        e.Handled = !matched;
    }

It works well for any combobox that uses data bound to a database, and is case insensitive. 它适用于使用绑定到数据库的数据的任何组合框,并且不区分大小写。 However, if the user inputs something in the wrong case and then tabs out of the combobox the combobox's selected value is still -1 (or whatever the previous value was). 但是,如果用户在错误的情况下输入了某些内容,然后在组合框中使用了制表符,则组合框的选定值仍为-1(或先前的值)。 That's not the behavior I want, I want it to set the value to what is currently the best guess at what the user is tying, ie the autocompleted option. 那不是我想要的行为,我希望它将值设置为当前最能猜出用户正在绑扎什么的值,即自动完成选项。

I have tried this, if you see the commented out line in the for loop. 如果您在for循环中看到注释掉的行,我已经尝试过了。 That doesn't work. 那不行
It does something like this: 它执行以下操作:
I have the field "Rent" with the value of 53 我的字段“租金”的值为53
I type 'r' 我输入“ r”
I get the result 'rRent' 我得到的结果是“ rRent”
combobox.SelectedValue returns -1 combobox.SelectedValue返回-1

What it currently does: 目前的功能:
I have the field "Rent" with the value of 53 我的字段“租金”的值为53
I type 'r' 我输入“ r”
Autocomplete suggests "rent" 自动完成提示“租金”
It's the correct value so I move on and the combobox loses focus 这是正确的值,所以我继续前进,组合框失去了焦点
Combobox displays "rent" 组合框显示“租金”
combobox.SelectedValue return -1 combobox.SelectedValue返回-1

What I want: 我想要的是:
I have the field "Rent" with the value of 53 我的字段“租金”的值为53
I type 'r' 我输入“ r”
The combobox loses focus, it fills in 'rent' (even though it's not in the correct case [already does this]) 组合框失去焦点,而是填写“租金”(即使不是在正确的情况下[已经这样做])
combobox.SelectedValue should now return 53 combobox.SelectedValue现在应该返回53

I think setting box.SelectedValue might be better but I can't figure out how to do that, at least in a high level abstracted way, if I knew how the combobox did it with ValueMemeber and Display member I would duplicate it but I don't. 我认为设置box.SelectedValue可能会更好,但我不知道如何做到这一点,至少以一种高级抽象的方式,如果我知道组合框是如何用ValueMemeber和Display成员做到的,我会复制它,但是我不知道“T。

Does anyone have any suggestions on how to resolve this bug? 有人对如何解决此错误有任何建议吗?

May be barking up the wrong tree, but have you tried just enabling auto complete on the combobox? 可能是树错了,但是您是否尝试过仅在组合框上启用自动完成功能?

comboBox.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
comboBox.AutoCompleteSource = AutoCompleteSource.ListItems;
comboBox.DropDownStyle = ComboBoxStyle.DropDownList;        

The last line will limit input to the items in the list. 最后一行将限制输入到列表中的项目。

It looks like I have no option but to do it in the LeaveFocus event, this handles the problem: 看来我别无选择,只能在LeaveFocus事件中执行此操作,这可以解决问题:

    protected void autocomplete_LeaveFocus(object sender, EventArgs e) {
        ComboBox box = ((ComboBox)sender);
        String selectedValueText = box.Text;

        //search and locate the selected value case insensitivly and set it as the selected value
        for (int i = 0; i < box.Items.Count; i++) {
            if (((DataRowView)box.Items[i])[box.DisplayMember].ToString().Equals(selectedValueText, StringComparison.InvariantCultureIgnoreCase)) {
                box.SelectedItem = box.Items[i];
                break;
            }
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM