How do you jump to a particular row in a DataGridView by typing (a la Windows Explorer details view)
I have a .NET Winforms app in C# with a DataGridView that's read-only and populated with some number of rows. I'd like to have functionality similar to Windows Explorer's (and many other applications) details view for example.
I'd like the DataGridView to behave such that when it has focus if you start typing, the current row selection will jump to the row where the (string) value of cell 0 (i.e. the first column in the row) starts with the characters you typed in.
For example, if I have a DataGridView with 1 column and the following rows:
- Bob
- Jane
- Jason
- John
- Leroy
- Sam
If the DataGridView has focus and I hit the 'b' key on my keyboard, the selected row is now "Bob". If I quickly type i开发者_开发知识库n the keys 'ja', the selected row is Jane. If I quickly type in the letters 'jas', the selected row is Jane. If I hit the 'z' key, nothing is selected (since nothing starts with Z).
Likewise if Jane is currently selected and I keep typing the letter 'j', the selection will cycle through to Jason, then John, then back to Jane, each time I hit the 'j' key.
I've been doing some Googling (and "stackoverflowing" :-)) for awhile and cannot find any examples of this type of functionality. I have a rough idea in my head to do this via some sort of short lived timer thread, collecting the keystrokes on KeyPress events for the DataGridView, and selecting rows based on those collected keystrokes matching a Cells[0].Value.StartsWith() type of condition. But it seems like there has to be an easier way that I'm just not seeing.
Any ideas would be much appreciated. Thanks!
I have not seen any built-in functionality like this on DataGridView. I'm pretty sure you'll have to "roll your own".
Are you looking for easier ways to do the "partial search" for the strings?
I wrote a method that will select row letter typed, perhaps you can modify per your needs. 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
精彩评论