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, i.e. the autocompleted option.
I have tried this, if you see the commented out line in the for loop. That doesn't work.
It does something like this:
I have the field "Rent" with the value of 53
I type 'r'
I get the result 'rRent'
combobox.SelectedValue returns -1
What it currently does:
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
What I want:
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?