VB Net Treeview Jump To Letter

J_K_M_A_N

I made a small time clock program and I used a treeview for listing the employees and their activity (Only 1 level deep).

I was looking for a way to jump to the next employee based on pressing the letter corresponding to the first letter of their first name. I could not find anything.

This is what I came up with.

Private Sub TryToJump(strLetter As String)
    Dim intSelectedNode As Integer
    Dim bolMatchFound As Boolean

    If tvEmployees.Nodes.Count = 0 Then Exit Sub 'There are no nodes to search through so exit the sub
    Dim tnTemp As TreeNode = tvEmployees.SelectedNode 'See if any node is selected
    If tnTemp Is Nothing Then
        intSelectedNode = 0 'No node was selected so start at 0 when searching
    Else
        intSelectedNode = tnTemp.Index + 1 'A node is selected so start the search at the node after the selected node
        If intSelectedNode >= tvEmployees.Nodes.Count Then 'If the selected node is the end of the line
            intSelectedNode = 0 'Start back at the beginning
        End If
    End If

    bolMatchFound = False 'Set a flag to determine if an entry was found or not
    For i As Integer = intSelectedNode To tvEmployees.Nodes.Count - 1 'go through each node starting at the first entry past the currently selected (or 0 if none are selected)
        If tvEmployees.Nodes(i).Parent Is Nothing Then 'This is a parent node so check the first letter
            If UCase(Strings.Left(tvEmployees.Nodes(i).Text, 1)) = UCase(strLetter) Then 'If the first letter matches
                tvEmployees.SelectedNode = tvEmployees.Nodes(i) 'Select that parent node 
                bolMatchFound = True 'Set the flag that the next match in line was found
                Exit For 'And exit the loop
            End If
        End If
    Next

    If Not bolMatchFound Then 'If we got to the end and there was not a match found
        For i As Integer = 0 To intSelectedNode 'Go through from the beginning up to the previously selected node
            If tvEmployees.Nodes(i).Parent Is Nothing Then 'If it is a parent
                If UCase(Strings.Left(tvEmployees.Nodes(i).Text, 1)) = UCase(strLetter) Then 'Check if the first letter matches
                    tvEmployees.SelectedNode = tvEmployees.Nodes(i) 'Select it if it does
                    Exit For 'And exit
                End If
            End If
        Next
    End If

End Sub

I am mostly self taught and this works but I am curious if some more experienced programmers would take a different approach.

This goes through all nodes (my list is not very big so it shouldn't be a problem with speed) and checks the first letter of every parent and selects that parent if there is a match.

If it gets to the end, it starts back at the beginning and goes until it hits the node that was originally selected. So the user can keep pressing 'M' for instance to get to their name.

Then users can get used to how many times they need to press it to get clocked in.
Again, it works but I am curious how others may handle this. Thanks.

Jimi

You could use Linq to locate the first TreeNode .Where() the item text .StartsWith() the search pattern and the TreeNode.Level = 0.

Then, make it visible using TreeNode.EnsureVisible().

You might also want to .SelectedNode = [FoundNode] to highlight it.

Here I'm using the TreeView KeyUp() event to trigger the search, but of course the FindNode() method could be called from anywhere else, provided that you can pass it a meaningful string.

When you change the seach patter, a new selection of TreeNodes is created and reused if the pattern doesn't change, so you don't need to parse the whole TreeView collection of nodes.
Pressing the same key will cycle through the TreeNodes selection.

Private CurrentNodeIndex As Integer = 0
Private TreeNodeSearchString As String = String.Empty
Private TreeNodeSelection As IEnumerable(Of TreeNode)

Private Sub tvEmployees_KeyUp(sender As Object, e As KeyEventArgs) Handles tvEmployees.KeyUp
    FindNode(Chr(e.KeyValue))
End Sub

Private Sub FindNode(sPattern As String)

    If sPattern <> TreeNodeSearchString Then
        TreeNodeSelection = tvEmployees.Nodes.
            Cast(Of TreeNode)().
            Where(Function(tn) (tn.Text.StartsWith(sPattern) AndAlso tn.Level = 0))

        CurrentNodeIndex = 0
        TreeNodeSearchString = sPattern
    End If

    If TreeNodeSelection.Count > 0 Then
        TreeNodeSelection(CurrentNodeIndex).EnsureVisible()
        tvEmployees.SelectedNode = TreeNodeSelection(CurrentNodeIndex)
        CurrentNodeIndex += 1
        If CurrentNodeIndex >= TreeNodeSelection.Count Then
            CurrentNodeIndex = 0
        End If
    End If

End Sub

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事