views:

1087

answers:

6

In WinForms 2.0, a ComboBox has an Auto-Complete feature, that displays a custom Drop-Down list with only the values that start with the entered text.

However, if I want to limit valid values to only those that appear in the ComboBox's list of items, I can do that by setting the DropDownStyle to DropDownList, which stops the user from entering a value.

However, now I can't use the Auto-Complete feature, which requires user input.

Is there another way to limit input to the list, while still allowing use of the Auto-Complete feature? Note that I have seen some custom solutions for this, but I really like the way the matching Auto-Complete items are displayed in a Drop-Down list, and sorted even though the original list may not be.

EDIT: I have thought about just validating the entered value, i.e. testing user input if it is valid in, say, the TextChanged event, or even using the Validating event. The question then is what is the expected behavior? Do I clear their value (an empty value is also invalid), or do I use a default value? Closest matching value?

P.s. Is there any other tags that I could add to this question?

A: 

The way I've done this is to check the value against the list of possible values when they leave the box and don't let them leave an invalid value. I don't know how you would want to handle it when you find that they've input an invalid value, but this is what I've done in the past.

Aaron Smith
+1  A: 

You could hook the keypress or textchanged event and validate that the text entered was an initial substring match for at least one of the list items, rejecting the keypress (or deleting the most recent character) if not. The only issue I can think of with this is that it may be a bit confusing to the user that some input is not accepted (particularly when typing the first character, at which point the autocomplete list won't be visible yet, so they won't know what valid values are).

Or just use it in dropdownlist mode - people can still type and it will jump to the first matching list item...

1. Doing the whole keypress thing is very annoying: you need to look out for all different keys, like BACKSPACE, ESCAPE, ENTER, etc.2. The list is not sorted, but is very long, so it is convenient that a different list appears (although this be confusing too, perhaps).
Schmuli
A: 

It might be as simple as this:

Private Sub cbx_Validating(ByVal sender As Object, ByVal e As _ System.ComponentModel.CancelEventArgs) Handles _ cbxZip.Validating, cbxCity.Validating, cbxCountry.Validating

    'Prerequisites: object: combobox, style: dropdownlist, 
    'autocompletesource=listitems, autocompletemode<>none
    'check if the typed value is in the list, else cancel
    'if the value isn't found, 'findstring' will return -1
    'if cancel is set to True, one can't leave the field
    e.Cancel = sender.FindStringExact(sender.Text) < 0
    'make it obvious to the user there is an issue
    If e.Cancel Then Beep()

End Sub

+1  A: 

Have you tried setting AutoCompleteMode = AutoCompleteMode.SuggestAppend and AutoCompleteSource = AutoCompleteSource.ListItems? That lets the user type, but it only accepts words that are in the ComboBox. The only catch is that the behavior has changed for Win7 (see http://stackoverflow.com/questions/2001361/combobox-selectedvalue-does-not-match-displayed-text-when-dropdownstyle-dropdow).

As for tags, you might try "combobox" and ".net".

Ecyrb
A: 

I was looking to do the same thing and came across this question. Here is what I've come up with.

Create a KeyDown event handler for the combobox and check for an Enter key. Note that after the user hits enter the text in the combobox is selected (as in, selected as if you were doing a cut or copy operation) and focus remains in the combobox.

If enter was pressed call a validation function that will do whatever you feel necessary if the value entered is good/bad.

You can call this same function in a Leave event handler to prevent the user from leaving the combobox until a valid selection is made.

private void uxWidgetsComboBox_KeyDown(object sender, KeyEventArgs e)
{
   if (e.KeyCode == Keys.Enter)
   {
      ValidateSelection();
   }
}

private void uxWidgetsComboBox_Leave(object sender, EventArgs e)
{
   if(!ValidateSelection())
   {
      uxWidgetsComboBox.Focus();
   }
}

Or something to that effect, but you get the idea.

Robert
A: 

You can set the "SuggestAppend property to SuggestAppend" and "AutoCompleteSource" to "ListItems" that will list and add the typed in characters by you in the drop down list. Also if not selected then even the apprpiate ValueMemeber would be selected for the drop down.

Meghag