Использование функции автозаполнения ComboBox при ограничении значений в списке?

17

В WinForms 2.0 ComboBox имеет функцию автозаполнения, которая отображает пользовательский раскрывающийся список только с значениями, начинающимися с введенного текста.

Однако, если я хочу ограничить допустимые значения только теми, которые отображаются в списке элементов ComboBox, я могу это сделать, установив DropDownStyle в DropDownList , что не позволяет пользователю ввести значение.

Однако теперь я не могу использовать функцию автозаполнения, которая требует ввода пользователем.

Есть ли другой способ ограничить ввод в список, сохраняя при этом возможность использования функции автозаполнения? Обратите внимание, что для этого я видел некоторые пользовательские решения, но мне очень нравится, как соответствующие элементы Auto-Complete отображаются в раскрывающемся списке и сортируются, даже если исходный список не может быть.

EDIT: я подумал только о проверке введенного значения, то есть тестировании ввода пользователя, если он действителен, например, в случае события TextChanged или даже с использованием события Validating . Тогда возникает вопрос, каково ожидаемое поведение? Удалить значение (пустое значение также недопустимо), или я использую значение по умолчанию? Ближайшее значение соответствия?

P.s. Есть ли еще теги, которые я мог бы добавить к этому вопросу?

    
задан Schmuli 14.01.2009 в 17:12
источник

9 ответов

4

Вы пытались установить AutoCompleteMode = AutoCompleteMode.SuggestAppend и AutoCompleteSource = AutoCompleteSource.ListItems ? Это позволяет ввести тип пользователя, но он принимает только слова, которые находятся в ComboBox . Единственный улов в том, что поведение изменилось для Win7 (см. ComboBox.SelectedValue не соответствует отображаемому тексту при DropDownStyle = DropDownList в Windows 7 ).

Что касается тегов, вы можете попробовать «combobox» и «.net».

    
ответ дан Ecyrb 13.01.2010 в 16:33
4

Это решение работало для меня:

Private Sub myComboBox_Validating(sender As System.Object, e As System.ComponentModel.CancelEventArgs) Handles myComboBox.Validating
    If Not myComboBox.Items.Contains(myComboBox.Text) Then
        MsgBox("Please select a value from the list", MsgBoxStyle.Exclamation, "Value not available")
        e.Cancel = True
    End If
End Sub
    
ответ дан StevenC 01.05.2013 в 12:05
3

Это может быть так просто:

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
    
ответ дан Danny 08.08.2009 в 07:35
2

Вы можете подключить событие keypress или textchanged и подтвердить, что введенный текст был исходным подстрочным совпадением для хотя бы одного из элементов списка, отклоняя нажатие клавиши (или удаление последнего символа), если нет. Единственная проблема, с которой я могу думать, заключается в том, что пользователь может немного смутить пользователя, что какой-то ввод не принят (особенно при наборе первого символа, после чего список автозаполнения еще не будет виден, поэтому они выиграли не знаю, какие значения действительны).

Или просто используйте его в режиме списка вниз - люди все еще могут печатать, и он перейдет к первому совпадающему элементу списка ...

    
ответ дан user6586 14.01.2009 в 18:18
  • 1. Выполнение всего нажатия клавиши очень раздражает: вам нужно искать все разные клавиши, например BACKSPACE, ESCAPE, ENTER и т. д. 2. Список не сортируется, но очень длинный, поэтому он удобен что появляется другой список (хотя это тоже может сбить с толку). –  Schmuli 14.01.2009 в 18:22
1

Вы можете установить для свойства «Свойство предложения» для «Предложения» и «Автокомпьютерный источник» для «ListItems», который будет отображать и добавлять введенные вами символы в раскрывающемся списке. Кроме того, если не выбран, то для раскрывающегося списка будет выбрано значение apprpiate ValueMemeber.

    
ответ дан Meghag 08.06.2010 в 09:58
0

То, как я это сделал, - это проверить значение в списке возможных значений, когда они покидают поле, и не позволяйте им оставлять недопустимое значение. Я не знаю, как вы хотели бы справиться с этим, когда обнаружите, что они ввели недопустимое значение, но это то, что я делал в прошлом.

    
ответ дан Aaron Smith 14.01.2009 в 17:17
0

Я хотел сделать то же самое и наткнулся на этот вопрос. Вот что я придумал.

Создайте обработчик событий KeyDown для combobox и проверьте наличие ключа Enter. Обратите внимание, что после того, как пользователь набрал, введите текст в поле со списком (как в, выбранном так, как если бы вы выполняли операцию вырезания или копирования), и фокус остается в выпадающем списке.

Если нажата клавиша ввода, вызовите функцию проверки, которая будет делать то, что вы считаете нужным, если введенное значение является хорошим / плохим.

Вы можете вызвать эту же функцию в обработчике события Leave, чтобы пользователь не покидал поле со списком до тех пор, пока не будет сделан правильный выбор.

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

Или что-то в этом роде, но вы получаете идею.

    
ответ дан Robert Groves 10.03.2010 в 03:51
0

У меня та же проблема ... Я задал тот же вопрос ( Как заставить пользователя принять предложенную запись в ComboBox? ), а затем я реализовал ее с помощью событий, но я получил много кода, который может улучшаться путем обобщения поведения ... скажите, пожалуйста, если вам это легко. Спасибо!

    
ответ дан JPCF 21.10.2011 в 00:30
0

Это сработало для меня. Я использовал DataTable как источник данных

 With cbo
    .AutoCompleteSource = AutoCompleteSource.ListItems
    .AutoCompleteMode = AutoCompleteMode.SuggestAppend
 End With

Private Sub cbo_Validating(sender As System.Object, e As System.ComponentModel.CancelEventArgs) Handles cbo.Validating
   If cbo.SelectedItem Is Nothing Then
       MessageBox.Show("Value entered not valid", "Message", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
       e.Cancel = True
   End If
End Sub
    
ответ дан Weapon X 06.10.2016 в 17:30