Search datagridview on user keypress

前端 未结 5 1273
别跟我提以往
别跟我提以往 2021-02-09 05:09

I\'m trying to select the first row where the cell value starts with the same keychar the user pressed. That\'s the part that is giving me trouble.

Here\'s how I\'m hand

相关标签:
5条回答
  • 2021-02-09 05:19

    Might be a case issue, is the Value in Cells["Name"] start with a capital letter? Try using ToUpper or ToLower on both; or you could try StartsWith(e.KeyChar, true) to ignoreCase. If you are trying to select the row, you'll want to do dataGridView1.Rows[i].Selected = true

    0 讨论(0)
  • 2021-02-09 05:21

    I use this in VB.NET. You can use http://www.developerfusion.com/tools/ to convert to C Sharp.

    I wrote a method that will select row letter typed. The function is called in the KeysPress event handler of the DataGridView.

    Method:

    'user types letter in dgv, method will select the column starting with that letter if it exists or else next letter existing in dgv
    Public Shared Sub GoToLetterTypedInDataGridView(ByVal dgv As DataGridView, ByVal columnName As String, ByVal columnPosition As Integer, ByVal letterTyped As Char)
        Try
            Dim dt As DataTable = dgv.DataSource
            Dim letter As Char = letterTyped
            Dim dv As DataView = New DataView(dt)
            Dim hasCount As Boolean = False
    
            While (Not hasCount)
                dv.Sort = columnName
                dv.RowFilter = columnName & " like '" & letter & "%'"
                If dv.Count > 0 Then
                    hasCount = True
                    Dim x As String = dv(0)(columnPosition).ToString()
                    Dim bs As New BindingSource
                    bs.DataSource = dt
                    dgv.BindingContext(bs).Position = bs.Find(columnName, x)
                    dgv.CurrentCell = dgv(0, bs.Position)
                Else
                    If letter = "z" Then
                        letter = "a"
                    ElseIf letter = "Z" Then
                        letter = "A"
                    Else : letter = Chr(Asc(letter) + 1)
                    End If
                End If
            End While
        Catch ex As Exception
            Dim stackframe As New Diagnostics.StackFrame(1)
            Throw New Exception("An error occurred in routine, '" & stackframe.GetMethod.ReflectedType.Name & "." & System.Reflection.MethodInfo.GetCurrentMethod.Name & "'." & Environment.NewLine & "  Message was: '" & ex.Message & "'")
        End Try
    End Sub
    

    Then to call:

    Private Sub dgvNew_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles dgvNew.KeyPress
    Try
        If dgvNew.RowCount > 0 Then
            GoToLetterTypedInDataGridView(dgvNew, "columnName", 0, e.KeyChar)
        End If
    Catch ex As Exception
        Dim stackframe As New Diagnostics.StackFrame(1)
        Throw New Exception("An error occurred in routine, '" & stackframe.GetMethod.ReflectedType.Name & "." & System.Reflection.MethodInfo.GetCurrentMethod.Name & "'." & Environment.NewLine & "  Message was: '" & ex.Message & "'")
    End Try
    

    End Sub

    Hope this helps! Amber

    0 讨论(0)
  • 2021-02-09 05:23

    The edited answer in the original question doesn't support jumping to the next letter if there are multiple instances of names starting with the same letter. Here is an edited answer which support this feature:

    private void dataGridView1_KeyPress(object sender, KeyPressEventArgs e)
    {
        if (Char.IsLetter(e.KeyChar))
        {
            int index = 0;
            // This works only if dataGridView1's SelectionMode property is set to FullRowSelect
            if (dataGridView1.SelectedRows.Count > 0 )
            {
                index = dataGridView1.SelectedRows[0].Index + 1
            }
            for (int i = index; i < (dataGridView1.Rows.Count + index); i++)
            {
                if (dataGridView1.Rows[i % dataGridView1.Rows.Count].Cells["Name"].Value.ToString().StartsWith(e.KeyChar.ToString(), true, CultureInfo.InvariantCulture))
                {
                    foreach (var row in dataGridView1.Rows.Cast<DataGridViewRow>().Where(t => t.Selected))
                    {
                        row.Selected = false;
                    }
                    dataGridView1.Rows[i % dataGridView1.Rows.Count].Cells[0].Selected = true;
                    return; // stop looping
                }
            }
        }
    }
    
    0 讨论(0)
  • 2021-02-09 05:25

    This is a VS2008 VB.NET DataGridView extension meant to do kind of what you are doing but using a TextBox for searching information (not designed with case in mind but could easily be added). This extension works so perhaps there is something that might be helpful. I did notice that your code selects a row using select where mine uses CurrentCell.

        <Runtime.CompilerServices.Extension()> _
    Public Function PartSeek(ByVal GridView As DataGridView, ByVal ColumnName As String, ByVal Value As String, ByVal Part As Boolean) As Boolean
        Dim Located As Boolean = False
    
        If GridView.Columns.Contains(ColumnName) Then
            Dim SingleRow As DataGridViewRow
            If Part Then
                SingleRow = (From Rows In GridView.Rows.Cast(Of DataGridViewRow)() _
                             Where Rows.Cells(ColumnName).Value.ToString().Contains(Value)).FirstOrDefault
            Else
                SingleRow = (From Rows In GridView.Rows.Cast(Of DataGridViewRow)() _
                             Where Rows.Cells(ColumnName).Value.ToString() = Value).FirstOrDefault
            End If
            If Not IsNothing(SingleRow) Then
                If GridView.CurrentCell.RowIndex <> SingleRow.Index Then
                    GridView.CurrentCell = GridView(0, SingleRow.Index)
                End If
                DirectCast(GridView.Parent, Form).ActiveControl = GridView
                Located = True
            End If
            Return Located
        Else
            Throw New Exception("Column '" & ColumnName & "' not contained in this DataGridView")
        End If
    
    End Function
    
    0 讨论(0)
  • 2021-02-09 05:34
    if (Char.IsLetterOrDigit(e.KeyChar))
    {
        foreach (DataGridViewRow dgvRow in myDgv.Rows)
        {
            if (dgvRow.Cells["ColumnName"].FormattedValue
                .ToString().StartsWith(e.KeyChar.ToString(), true, CultureInfo.InvariantCulture))
            {
                dgvRow.Selected = true;
                break;
            }
        }
    }
    

    If the DGV is set up to allow Multi-Select then you'd obviously want to deselect any existing selection.

    0 讨论(0)
提交回复
热议问题