简体   繁体   中英

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). 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. That doesn't work.

I have the field "Rent" with the value of 53
I type 'r'
I get the result 'rRent'
combobox.SelectedValue returns -1


I have the field "Rent" with the value of 53
I type '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


I have the field "Rent" with the value of 53
I type '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

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.

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:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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