У нас есть устаревшее приложение, написанное на VB6, использующее элемент управления Microsoft TreeView
по умолчанию для отображения иерархических данных. Поскольку в этом TreeView
содержится много информации, мы подумали о реализации небольшой возможности фильтрации / поиска для пользователей.
Первая попытка состояла в том, чтобы переключить видимость и сделать видимыми только узлы (и их родителей), которые соответствуют заданному поиску. Но это было невозможно, так как элемент управления Microsoft TreeView
по умолчанию не позволяет их узлам быть видимыми или невидимыми.
Таким образом, вторая попытка состоит в том, чтобы обойти все узлы в дереве и обеспечить видимость узла, когда он соответствует определенному поиску (и прекратить обход). Если найденный узел не тот, который ищет пользователь, он может «продолжить» поиск и найти следующий узел, который соответствует его критериям.
Пока это работает довольно хорошо, за исключением одной маленькой проблемы. Поиск не работает сверху вниз, так как дерево заполняется данными в случайном порядке сортировки, а затем сортируется путем установки свойства Sorted
каждого узла (устаревший код). Таким образом, поиск проходит по случайно добавленным узлам, и найденные узлы «перепрыгивают» между узлами верхнего уровня (коллекция Nodes
TreeView
содержит все узлы в порядке их добавления, а не только узлы верхнего уровня а не в том порядке, в котором они представлены пользователю).
Есть ли способ получить все узлы дерева в том порядке, в котором они показаны пользователю? Я не люблю менять устаревший код, который заполняет дерево данными, и сортировка данных перед их добавлением в TreeView
может повлиять на производительность.
Обратите внимание, что я имею в виду приложение, написанное на VB6 , поэтому нет такой вещи, как LINQ для обхода узлов в нужном порядке.
Вот мой поисковый код:
Private Sub cmdSearch_Click()
Dim oMatch As Node
Set oMatch = GetNextMatch
If Not (oMatch Is Nothing) Then
oMatch.EnsureVisible
oMatch.Selected = True
Me.TreeView1.SelectedItem = oMatch
Me.TreeView1.SetFocus
End If
End Sub
Private Function GetNextMatch() As Node
Dim lIndex As Long
Dim oResult As Node
For lIndex = mlLastFoundIndex + 1 To Me.TreeView1.Nodes.Count
If IsMatch(Me.TreeView1.Nodes(lIndex).Text) Then
Set oResult = Me.TreeView1.Nodes(lIndex)
mlLastFoundIndex = lIndex
Exit For
End If
Next lIndex
Set GetNextMatch = oResult
End Function
Private Sub txtSearch_Change()
mlLastFoundIndex = 0
End Sub