Получить узлы TreeView в отсортированном порядке - PullRequest
2 голосов
/ 07 марта 2019

У нас есть устаревшее приложение, написанное на 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
...