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.
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]
コメントを追加