Событие SelectedIndexChanged ComboBox не вызывается при вводе

я работаю над VS 2010 с VB с помощью .NET Framework 4.0

у меня есть combobox. Он имеет некоторые элементы в нем и отображает просто отлично. Вот где это становится немного странным:

если я нажму стрелку раскрывающегося списка на combobox и нажмите на элемент, который я хочу,SelectedIndexChanged - Это называется - хорошо.

если я нажму внутри текстовой области combobox и начните вводить то, что я хочу выбрать, и закончите его, нажав клавишу вверх (или вниз),SelectedIndexChanged называется - тоже хороший.

если я нажму стрелку раскрывающегося списка на combobox и начните вводить то, что я хочу выбрать, и закончите его, нажав ENTER,SelectedIndexChanged не называется - проблема.

есть ли другое событие, вызванное ENTER в последнем случае? Я пробовал использовать TextChanged и TextUpdate события, но они, похоже, не работают:

Private Sub cmbStatus_TextChanged(sender As System.Object, e As System.EventArgs) Handles cmbStatus.TextChanged
If e.Equals(Keys.Enter) Then
    Call SomeMethod()
End If

должен ли я использовать что-то кроме e.Equals(Keys.Enter)?

есть ли еще одно событие, которое я должен искать для?

EDIT: Пример элементов в ComboBox являются:

  • 10-НОВАЯ ЗАПИСЬ И ПРОВЕРКА ПОЛНОТЫ ---> this is the most common type
  • 13 - ПРИСВОЕНО TRB / HRB ---> there are a few with '/'
  • 60-ВНЕШНИЙ (УДЕРЖИВАЙТЕ ДО ДАЛЬНЕЙШЕГО УВЕДОМЛЕНИЯ)---> there are a few with '(' and ')'

в основном, тип каждого списка - "# # - некоторый текст".

9 ответов


Option Strict On
Public Class Form1
    Friend WithEvents ComboBox1 As New ComboBox With {.Parent = Me}
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
        ComboBox1.Items.AddRange({"hello", "tes1ted", "word", "item", "tes2ted"})
        ComboBox1.Text = ComboBox1.Items(0).ToString
    End Sub
    Private Sub ComboBox1_KeyUp(ByVal sender As Object, ByVal e As KeyEventArgs) Handles ComboBox1.KeyUp
        'You can put this in the keydown event, or adapt it a small bit and put it in the keypress event
        'putting it in the textchanged event is problematic and not recommended.
        Dim OriginalText As String = ComboBox1.Text
        If e.KeyCode = Keys.Enter Then
            If ComboBox1.SelectionLength > 0 Then
                ComboBox1.Text = ComboBox1.Text
                ComboBox1.SelectionLength = 0
                ComboBox1.SelectionStart = ComboBox1.Text.Length
            End If
        End If
        If Not IsTextKey(e.KeyCode) Then Exit Sub
        Dim Filter As String = ComboBox1.Text & "*"
        If Filter.Length = 1 Then Exit Sub
        For I = 0 To ComboBox1.Items.Count - 1
            If LCase(ComboBox1.Items(I).ToString) Like LCase(Filter) Then
                ComboBox1.SelectedItem = ComboBox1.Items(I)
                ComboBox1.Select(OriginalText.Length, (ComboBox1.Text.Length - OriginalText.Length))
                Exit Sub
            End If
        Next
    End Sub
    Function IsTextKey(ByVal Key As Integer) As Boolean
        Select Case True
            Case Key = Keys.Up : Return False
            Case Key = Keys.Down : Return False
            Case Key = Keys.Left : Return False
            Case Key = Keys.Right : Return False
            Case Key = Keys.Back : Return False
            Case Key = Keys.Delete : Return False
            Case Key = Keys.LWin : Return False
            Case Key = Keys.RWin : Return False
                'add whatever I missed
                'return false if the key either removes text from the textbox 
                'or does not produce a character
            Case Else
                'return true if the key produces a visible character(including space)
                Return True
        End Select
    End Function
End Class

отказ от ответственности: это написано на C# - дайте мне знать, если вам нужно перевести его на VB.

private void comboBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
    //It's important to also check that the Combo Box is displaying its Drop Down. If
    //you want this to execute even when it is not displayed, remove the check for
    //comboBox1.DroppedDown.
    if (e.KeyCode == Keys.Enter && comboBox1.DroppedDown &&
        !string.IsNullOrEmpty(comboBox1.Text))
    {
        int index;
        //Attempt to locate the string typed in by the user. An index of -1
        //means it was not found.
        if ((index = comboBox1.FindStringExact(comboBox1.Text)) != -1)
        {
            //Update the SelectedIndex.
            comboBox1.SelectedIndex = index;
        }
    }
}

интересно, что docs говорят, что мы должны использовать SelectionChangeCommitted событие вместо SelectedIndexChanged событие при обработке изменений выбора, сделанных пользователем. Это необходимо сделать в этом случае как SelectedIndexChanged событие дважды, используя мой подход.

Edit:

чтобы запретить пользователю вводить всю строку, используйте совет из ответа Adi: перейдите в свойства поля со списком и установите set AutoCompleteMode до SuggestAppend и AutoCompleteSource to ListItems - Я actully использовал эти настройки при создании моего ответа, поэтому он должен работать для вас.


Private Sub ComboBox1_KeyUp(sender As System.Object, e As System.Windows.Forms.KeyEventArgs) Handles ComboBox1.KeyUp
    If e.KeyCode = Keys.Enter Then
        MessageBox.Show(ComboBox1.SelectedText)
        Call SomeMethod()
    End If
End Sub

Я считаю, что вы должны установить AutoCompleteMode до SuggestAppend и AutoCompleteSource to ListItems. Таким образом, если то, что вы вводите, устойчиво с элементами, загруженными в ComboBox, записав его и найдя этот элемент, при нажатии Enter, the SelectedIndexChanged будет уволен (даже если матч не будет найден - будет выбран первый в списке)

Я приготовил что-то указать на это вы.

С уважением,

Ади Константин


подпишитесь на событие KeyPressed:

Private Sub yourComboBox_KeyPressed(sender As System.Object, e As System.KeyPressedEventArgs) Handles yourComboBox.KeyPressed
    If e.KeyChar.Equals((char)Keys.Enter) Then
        Call SomeMethod()
End If

это поможет вашим проблемам

 Private Sub ComboBox1_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles ComboBox1.KeyDown
    If e.KeyCode = Keys.Enter Then
        MsgBox("hello")'call some functions
    End If
End Sub

можете ли вы дайте мне знать, если это работает для вас?

    Private Sub ComboBox1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles ComboBox1.KeyPress
      If e.KeyChar = Chr(13) Then
        ComboBox1_SelectedIndexChanged(sender, e)
      End If
    End Sub

    Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
      MsgBox(ComboBox1.Text)
      'Your code here
    End Sub

У меня была аналогичная проблема, когда ComboBox dropdownstyle был установлен в простой с автозаполнением, чтобы добавить, источник из моих listitems. Мой обходной путь должен был иметь строковую переменную, сохраняющую текст combobox при каждом событии textchanged. Таким образом, при нажатии ENTER вы можете получить удаленный текст и переназначить его в текст combobox.

'глобальная декларация

'Global declaraion
dim selected_text as string = ""

 Private Sub combobox_textchanged(sender As Object, e As EventArgs) Handles combobox.TextChanged
        If combobox.Text IsNot Nothing And combobox.Text <> "" Then
            selected_text = combobox.Text
        End If
 End Sub

Private Sub combobox_keydown(sender As Object, e As KeyEventArgs) Handles combobox.KeyDown
        If e.KeyCode = Keys.Enter Then
            combobox.Text = selected_text
            'put logic here
        End If
End Sub

есть несколько отличных ответов выше, но мне понравилось, что мне не нужно было сортировать все клавиши управления и стрелки etc.


закройте список вручную на PreviewKeyDown событие:

Private Sub cmbStatus_PreviewKeyDown(sender As ComboBox, e As PreviewKeyDownEventArgs) Handles cmbStatus.PreviewKeyDown
    If e.KeyCode = Keys.Enter Then sender.DroppedDown = False
End Sub