Member 11856456 Ответов: 1

Итерация и удаление дубликатов узлов дерева из базы данных в treeview


Итак, я смог объединить 2 метода, чтобы придумать способ удаления дубликатов узлов дерева. Прямо сейчас моя проблема в том, что я могу сделать только 1 итерацию на каждую функцию, которая у меня есть. Я хочу иметь возможность использовать одну и ту же функцию и выбирать несколько ячеек для заполнения древовидного изображения. То, что у меня нет, отлично работает, если все, что вы хотите, это 1 столбец, генерирующий treeview без дубликатов. Вот что у меня сейчас есть:

Private Function Searchnode(ByVal nodetext As String, ByVal treeview1 As TreeView) As TreeNode

       Dim newNode As TreeNode = New TreeNode(nodetext)

       For Each node As TreeNode In treeview1.Nodes(0).Nodes
           If node.Text = nodetext Then
               node.Remove()

           End If
       Next

       treeview1.Nodes(0).Nodes.Add(newNode)
       Return newNode


   End Function


   Public Sub Remove_treeview_duplicates()
       TreeView1.Nodes.Add("treenode")

       Dim node As TreeNode

       For Each row As DataRow In Database1DataSet.Table.Rows
           'search in the treeview if node is already present
           node = Searchnode(row.Item(3).ToString(), TreeView1)

       Next

   End Sub


Я хочу сгенерировать treeview без повторяющейся информации с определенными Row. items, а не только 1.

Что я уже пробовал:

Я сделал другие функции, чтобы сделать те же эффекты, но должен быть способ для 1 функции контролировать лот.

1 Ответов

Рейтинг:
6

Wendelius

Не уверен, правильно ли я понял вопрос, но из того, что я понял, вы хотите удалить соответствующие узлы независимо от того, на каком уровне они найдены. Для этого вам нужна рекурсия.

Взгляните на следующий пример. Сначала я добавляю некоторые узлы в древовидное представление, а затем удаляю все элементы, содержащие текст B

    Dim treenode As TreeNode

    ' Add example data
    treenode = Me.TreeView1.Nodes.Add("A")
    treenode.Nodes.Add("B")
    treenode.Nodes.Add("C")

    treenode = Me.TreeView1.Nodes.Add("B")
    treenode = treenode.Nodes.Add("C")
    treenode.Nodes.Add("D")

    treenode = Me.TreeView1.Nodes.Add("C")
    treenode = treenode.Nodes.Add("B")
    treenode.Nodes.Add("A")

    'recursively remove desired nodes
    Me.RemoveNodesByText("B", Me.TreeView1)


End Sub

Private Function RemoveNodesByText(ByVal nodetext As String, ByVal treeview1 As TreeView, Optional childnode As TreeNode = Nothing) As Boolean
    Dim nodesToIterate As TreeNodeCollection

    If childnode Is Nothing Then
        nodesToIterate = treeview1.Nodes
    Else
        nodesToIterate = childnode.Nodes
    End If

    For nodecounter As Integer = nodesToIterate.Count - 1 To 0 Step -1
        ' recursively loop through children
        RemoveNodesByText(nodetext, treeview1, nodesToIterate(nodecounter))
        ' remove this node if matches the given node text
        If nodesToIterate(nodecounter).Text = nodetext Then
            nodesToIterate(nodecounter).Remove()
        End If
    Next

    Return True
End Function

Одна вещь заключается в том, что в примере кода новый узел не добавляется внутри рекурсивной функции. В противном случае будет создано несколько новых узлов, поэтому, если вы хотите убедиться, что существует только один узел в своем роде, сначала удалите дубликаты, а затем добавьте новый узел в нужное место.


Member 11856456

Это очень интересный код, но когда я запускаю его на основе текста, он удаляет весь текст, который является "B". То, что я хочу сделать, основываясь на вашем примере, заключается в том, что если база данных имеет 3 B, то я хочу только 1 B.

Wendelius

Обратите внимание, конечно, если я понимаю. Вы добавляете узел для всех строк, которые пришли из базы данных, и хотите, чтобы осталась только последняя?

Например
- А извлечена из базы данных, добавленных к узлам
- B извлекается из базы данных, B добавляется в узлы
- C извлекается из базы данных, c добавляется в узлы
- B извлечен из базы данных, preivous B удален, новый B добавлен в узлы
- и так далее...

Member 11856456

Поэтому, как только я получаю базу данных в treeview, у меня есть столбец округа и столбец штата. Например, я использовал Кентукки в качестве штата, и здесь у меня есть 3 разных округа.

Кентукки-
Флойд
Флойд
Флойд
Флойд
Джефферсон
Джефферсон
Джефферсон
Щука
Щука

то, что я хочу сделать, это удалить дублированный текст и сохранить только 1 из каждого

Кентукки-
Флойд
Джефферсон
Щука

это просто пример, у меня есть другие колонки, которые я хотел бы сделать таким же образом в то же время.

Wendelius

Хорошо, рекурсивная функция в основном справилась бы с этим, если бы у вас была следующая логика

для каждой строки в datatable
RemoveNodesByText (row ("county"), treeview1)
Элемента управления treeview1.Узлы.Добавить (строка ("округ"))
следующий

это гарантировало бы, что останется только последнее.

Однако это не решит ситуацию для нескольких столбцов. Если вы удаляете узлы также на основе текста в других столбцах, что делать, если комбинация столбцов уникальна, должна ли она остаться?

Чем больше информации вы предоставляете, тем больше это звучит так, как будто вам нужно будет изменить запрос базы данных, чтобы возвращать только уникальные комбинации. Например, если у вас сейчас есть

выберите округ, город, штат из mytable

вы можете использовать ключевое слово distinct для удаления дубликатов при извлечении данных:

выберите отдельный округ, город, штат из mytable

Таким образом, вам не нужно будет удалять уже добавленные узлы.