首页 > 解决方案 > VB.net自动完成字符串选择后如何使DataGridView移动到下一个单元格而不是下一行?

问题描述

我有一个 DataGridView,其中一些单元格只允许来自 AutoCompleteStringCollection 的值。当我进入单元格并开始输入值时,会出现一个下拉窗口,其中包含可行的选项。如果我完成输入并按 Enter 或 Tab,我会转到下一个单元格。但是,如果我开始输入,然后从下拉菜单中选择一个选项,它会在同一列中向下移动一行。从下拉框中选择后,我希望它移动到下一个单元格/下一列 SAME 行。知道我如何去做这件事。在此先感谢您的帮助!!

Private Sub getData(ByVal DataCol As AutoCompleteStringCollection)
    Dim comm As SqlCommand
    Dim adapt As New SqlDataAdapter
    Dim ds As New DataSet

    Dim sql As String = "SELECT DISTINCT ValueOption From HR.dbo.RecruitVal WHERE ColumnName = 'Source'"

    Try

        If SqlConn.State = ConnectionState.Broken Then SqlConn.Close()
        If SqlConn.State = ConnectionState.Closed Then SqlConn.Open()

        comm = New SqlCommand(sql, SqlConn)
        adapt.SelectCommand = comm
        adapt.Fill(ds)
        adapt.Dispose()
        comm.Dispose()
        For Each row As DataRow In ds.Tables(0).Rows
            DataCol.Add(row(0).ToString())
        Next
    Catch ex As Exception
        MessageBox.Show("Error")
    End Try

End Sub


Private Sub RAppSrc(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles RAppGrid.EditingControlShowing
    Dim titleText As String = RAppGrid.Columns(RAppGrid.CurrentCell.ColumnIndex).HeaderText
    If titleText.Equals("Source") Then
        Dim autoText As TextBox = TryCast(e.Control, TextBox)
        If autoText IsNot Nothing Then
            autoText.AutoCompleteMode = AutoCompleteMode.SuggestAppend
            autoText.AutoCompleteSource = AutoCompleteSource.CustomSource
            Dim dataCol As New AutoCompleteStringCollection()
            getData(dataCol)
            autoText.AutoCompleteCustomSource = dataCol
        End If
    End If
End Sub

单元格 - 验证

    If (appCol.Name = "Source") Then
        Dim sql As String = " SELECT 1 FROM Hr.dbo.RecruitVal WHERE ColumnName = 'Source'AND ValueOption = @Source "
        Dim sql2 As String = "SELECT DISTINCT ValueOption from HR.dbo.RecruitVal WHERE ColumnName = 'Source' "
        Dim com As New SqlCommand(sql, SqlConn)
        Dim com2 As New SqlCommand(sql2, SqlConn)
        Dim reader As SqlDataReader
        Dim val As String
        Dim val2 As String
        com.Parameters.Add("@Source", SqlDbType.VarChar).Value = e.FormattedValue
        val = com.ExecuteScalar()
        reader = com2.ExecuteReader()
        If reader.HasRows Then
            While reader.Read()
                val2 += reader.GetValue(0) & "," & Space(3)
            End While
        End If
        If String.IsNullOrEmpty(e.FormattedValue) Then
            'Do Nothing
        ElseIf val = Nothing Then
            MessageBox.Show(" Please Enter a valid Source Option" & vbCrLf & vbCrLf & "Valid Options are as Follows:" & vbCrLf & vbCrLf + val2.ToString(), "VALIDATION ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error)
            RAppGrid.EndEdit()
        End If
    End If

标签: vbavb.netvisual-studiodatagridviewautocomplete

解决方案


我已经测试了几个场景并发现该Enter密钥不起作用(所有但都Enter有效)。我在 MSDN 上找到了这个答案

对于 enter 键,ProcessDataGridViewKey 将返回 true 表示它已经处理了该键,因此您不会收到 KeyDown 事件。

如果您覆盖 ProcessDataGridViewKey 并处理回车键使其返回 false,您将获得您期望的关键事件。

{
 Keys key = (e.KeyCode & Keys::KeyCode); //removes control, alt modifiers
  if(key == Keys.Enter)
 {
   //Still do the default processing for enter so it will move down to the next row
   Base.ProcessDataGridViewKey(e);
   return false; //say we have *not* handled the key
 }
 else
 {
   return Base.ProcessDataGridViewKey(e);
 }
}

上面的代码显然是用 C# 编写的。

然后移动功能可能看起来像这样(仅测试了下面的 VB.NET 版本,并且仅使用除 之外的其他键Enter):

Private Sub DataGridView1_EditingControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
    If IsNothing(TryCast(e.Control, DataGridViewTextBoxEditingControl)) = False Then
        Dim tb As DataGridViewTextBoxEditingControl = e.Control
        AddHandler e.Control.KeyDown, AddressOf DataGridView1_Keydown
    End If
End Sub

Private Sub DataGridView1_Keydown(sender As Object, e As KeyEventArgs) ' Handles DataGridView1.KeyDown
    Dim dgv As DataGridView = DataGridView1
    Dim tb As TextBox = CType(sender, TextBox)
    If e.KeyCode = Keys.Enter Then
        e.SuppressKeyPress = True
        dgv.EndEdit()
        If IsNothing(dgv.CurrentCell) = False Then
            Dim cc As DataGridViewCell = dgv.CurrentCell
            If cc.ColumnIndex < dgv.Columns.Count - 2 Then ' if there's a cell to the right of the current one
                dgv.CurrentCell = dgv.Rows(cc.RowIndex).Cells(cc.ColumnIndex + 1)
            ElseIf cc.RowIndex < dgv.Rows.Count - 1 Then   ' if there's a row bellow
                dgv.CurrentCell = dgv.Rows(cc.RowIndex + 1).Cells(0)
            Else
                ' do nothing, stay where you are
            End If
            dgv.CurrentCell.Selected = True
        End If
    End If
End Sub

推荐阅读