Использовать функцию автозаполнения ComboBox, ограничивая значения в списке?
В WinForms 2.0 ComboBox имеет функцию автозаполнения, которая отображает пользовательский раскрывающийся список только с значениями, начинающимися с введенного текста.
Однако, если я хочу ограничить допустимые значения только теми, которые появляются в списке элементов ComboBox, я могу сделать это, установив DropDownStyle
в DropDownList
, что не позволяет пользователю ввести значение.
Однако теперь я не могу использовать функцию автозаполнения, которая требует ввода пользователем.
Есть ли другой способ ограничить ввод в список, сохраняя при этом возможность использования функции автозаполнения? Обратите внимание, что для этого я видел некоторые пользовательские решения, но мне очень нравится, как соответствующие элементы Auto-Complete отображаются в раскрывающемся списке и сортируются, даже если исходный список не может быть.
EDIT: Я подумал о том, чтобы просто подтвердить введенное значение, то есть проверить ввод пользователя, если он действителен, например, в событии TextChanged
, или даже с помощью события Validating
. Тогда возникает вопрос, каково ожидаемое поведение? Удалить значение (пустое значение также недопустимо), или я использую значение по умолчанию? Ближайшее значение соответствия?
P.s. Есть ли еще теги, которые я мог бы добавить к этому вопросу?
Ответы
Ответ 1
Вы пытались установить AutoCompleteMode = AutoCompleteMode.SuggestAppend
и AutoCompleteSource = AutoCompleteSource.ListItems
? Это позволяет ввести тип пользователя, но он принимает только слова, которые находятся в ComboBox
. Единственный улов в том, что поведение изменилось для Win7 (см. ComboBox.SelectedValue не соответствует отображаемому тексту при DropDownStyle = DropDownList в Windows 7).
Что касается тегов, вы можете попробовать "combobox" и ".net".
Ответ 2
Это решение работало для меня:
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
Ответ 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
Ответ 4
Вы можете подключить событие keypress или textchanged и подтвердить, что введенный текст был исходным подстрочным совпадением для хотя бы одного из элементов списка, отклоняя нажатие клавиши (или удаление последнего символа), если нет. Единственная проблема, с которой я могу думать, заключается в том, что пользователь может немного смутить пользователя, что какой-то ввод не принят (особенно при наборе первого символа, после чего список автозаполнения еще не будет виден, поэтому они выиграли не знаю, какие значения действительны).
Или просто используйте его в режиме списка вниз - люди все еще могут печатать, и он перейдет к первому совпадающему элементу списка...
Ответ 5
Вы можете установить для свойства "Свойство предложения" для "Предложения" и "Автокомпьютерный источник" для "ListItems", который будет отображать и добавлять введенные вами символы в раскрывающемся списке.
Кроме того, если не выбран, то для раскрывающегося списка будет выбрано значение apprpiate ValueMemeber.
Ответ 6
То, как я это сделал, - это проверить значение в списке возможных значений, когда они покидают поле, и не позволяйте им оставлять недопустимое значение. Я не знаю, как вы хотели бы справиться с этим, когда обнаружите, что они ввели недопустимое значение, но это то, что я делал в прошлом.
Ответ 7
Я хотел сделать то же самое и наткнулся на этот вопрос. Вот что я придумал.
Создайте обработчик событий 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();
}
}
Или что-то в этом роде, но вы получаете идею.
Ответ 8
У меня та же проблема... Я задал тот же вопрос (Как заставить пользователя принять предложенную запись в ComboBox?) и то я реализовал его с событиями, но я получил много кода, который можно улучшить, обобщая поведение... скажите, пожалуйста, если вам это легко. Спасибо!
Ответ 9
Это сработало для меня.
Я использовал 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