2017-01-30 5 views
1

Хорошего дня,Populate Treeview используя Список предметов

У меня есть два списка объектов (скажем, например, MyObjList в качестве нового списка (Integer)) и на основании их показатели я хочу построить TreeView, начиная с пункта 0 и заканчивается последним элементом в списке. Я хочу, чтобы эти объекты отображались как показано ниже. Я могу добавить первый узел, но после этого не могу понять, как добавить следующий узел в качестве дочернего элемента каждого ранее добавленного узла (если это имеет смысл). Поблагодарили бы за вашу помощь. Я добавил изображение, чтобы лучше понять, как я хочу, чтобы оно выглядело как против того, что я получаю в данный момент, основываясь на нижних ответах. treeview populated with two lists of objects

0--> 
    1 
    --> 
     2 
     --> 
      3--> 
       4 


     Dim myObjList As New List(Of integer) 
      myObjList.Add("0") 
      myObjList.Add("1") 
      myObjList.Add("2") 
      myObjList.Add("3") 
      myObjList.Add("4") 

Можем ли мы достичь этого?

Can we achieve this

ответ

2

Если я правильно понял, вы пытаетесь добавить Nodes так что TreeView выглядит следующим образом:

enter image description here

Это то, что это будет выглядеть как вручную:

TreeView1.Nodes.Add(list(0).ToString()) 
TreeView1.Nodes(0).Nodes.Add(list(1).ToString()) 
TreeView1.Nodes(0).Nodes(0).Nodes.Add(list(2).ToString()) 
TreeView1.Nodes(0).Nodes(0).Nodes(0).Nodes.Add(list(3).ToString()) 
TreeView1.Nodes(0).Nodes(0).Nodes(0).Nodes(0).Nodes.Add(list(4).ToString()) 

Это, конечно, настоящая боль и не масштабируема. То, что я хотел бы посмотреть на это вместо рекурсивно добавление ребенка Nodes к TreeView, как например:

Public Class Form1 

    Dim list As New List(Of Integer) 

    Private Sub AddMoreChildren(ByVal parent As TreeNode) 

     If parent.Level < list.Count - 1 Then 
      Dim child As New TreeNode(list(parent.Level + 1).ToString()) 

      parent.Nodes.Add(child) 

      AddMoreChildren(child) 
     End If 

    End Sub 

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 

     list.Add(0) 
     list.Add(1) 
     list.Add(2) 
     list.Add(3) 
     list.Add(4) 

     Dim root As New TreeNode(list.First.ToString()) 
     AddMoreChildren(root) 
     TreeView1.Nodes.Add(root) 

    End Sub 

End Class 

Из кода выше вы достичь того же результата, как видно на скриншоте.

Красота заключается в том, что код будет продолжать звонить AddMoreChildren, пока не будут добавлены все элементы в List.

Edited включить два списка

Если у вас есть два списка, то, что я хотел бы посмотреть на это делать приведение их вместе, чтобы создать отчетливый List с помощью Concat и Distinct.

Обратите внимание, что я теперь изменил свое List с, чтобы иметь тип String для этого примера и больше не нужно использовать .ToString при установке значения.

Public Class Form1 

    Dim firstList As New List(Of String) 
    Dim secondList As New List(Of String) 
    Dim mainList As New List(Of String) 

    Private Sub AddMoreChildren(ByVal parent As TreeNode) 

     If parent.Level < mainList.Count - 1 Then 
      Dim child As New TreeNode(mainList(parent.Level + 1)) 

      parent.Nodes.Add(child) 

      AddMoreChildren(child) 
     End If 

    End Sub 

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 

     firstList.Add("S") 
     firstList.Add("A3") 
     firstList.Add("U13") 
     firstList.Add("ABC") 
     firstList.Add("PQ") 
     firstList.Add("1234") 

     secondList.Add("S") 
     secondList.Add("A3") 
     secondList.Add("U13") 
     secondList.Add("XYZ") 
     secondList.Add("ST") 
     secondList.Add("5678") 

     mainList = firstList.Concat(secondList).Distinct().ToList() 

     Dim root As New TreeNode(mainList.First) 
     AddMoreChildren(root) 
     TreeView1.Nodes.Add(root) 

    End Sub 

End Class 

Это даст вам следующий вывод:

enter image description here

Edit на основе обновления OP в

Это то, что ФП после на основе обновления:

enter image description here

Для этого требуется немного больше кода и не такой аккуратный, но он выполняет эту работу. В этом случае я должен ввести другую переменную под названием index. Это чисто для отслеживания текущего индекса в mainList вместо использования If parent.Level.

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

Сначала позвоните Intersect. Это используется, чтобы получить список, где значения находятся в обоих firstList и secondList оставив нас с S, A3 и U13:

Dim root As TreeNode 
mainList = firstList.Intersect(secondList).ToList() 
root = New TreeNode(mainList.First) 

Теперь, когда мы это будем идти вперед и добавить их в TreeView:

index = 1 
AddMoreChildren(root) 
TreeView1.Nodes.Add(root) 

Я установил index к здесь, потому что у меня уже есть корневой узел и хочу т o начинаются с A3 когда я иду в AddMoreChildren. Там также было небольшое изменение метода AddMoreChildren:

Private Sub AddMoreChildren(ByVal parent As TreeNode) 

    If index < mainList.Count Then 
     Dim child As New TreeNode(mainList(index).ToString()) 

     parent.Nodes.Add(child) 

     index += 1 

     AddMoreChildren(child) 
    End If 

End Sub 

Обратите внимание на использование index теперь вместо parent.Level.

Далее, так как вы хотите, чтобы расшириться от U13 мы должны получить индекс этого. Это делается довольно просто:

Dim indexOfLastNode As Integer = mainList.Count - 1 

Далее мы устанавливаем U13 в качестве корневого узла:

root = GetLastAddedChildNode(TreeView1.Nodes(0), indexOfLastNode) 

Код для GetLastAddedChildNode является:

Private Function GetLastAddedChildNode(ByVal parentNode As TreeNode, 
             ByVal level As Integer) As TreeNode 

    Dim newNode As New TreeNode 

    For Each node As TreeNode In parentNode.Nodes 
     If node.Level = level Then 
      newNode = node 
      Exit For 
     End If 
     newNode = GetLastAddedChildNode(node, level) 
    Next 

    Return newNode 

End Function 

Тогда манипулировать mainList так что мы получаем все значения от firstList, которые не находятся в secondList. Это дает нам ABC, PQ и . Мы делаем это, используя Except.Затем мы можем назвать AddMoreChildren и добавить ABC, PQ и к U13.

Обратите внимание, не забудьте сбросить index до 0 перед вызовом AddMoreChildren, так что мы можем получить все элементы в mainList добавлены.

Затем мы делаем то же самое для secondList, используя Except. Вот полный код одним махом. Это может иметь больше смысла:

Public Class Form1 

    Dim firstList As New List(Of String) 
    Dim secondList As New List(Of String) 
    Dim mainList As New List(Of String) 

    Dim index As Integer 

    Private Sub AddMoreChildren(ByVal parent As TreeNode) 

     If index < mainList.Count Then 
      Dim child As New TreeNode(mainList(index).ToString()) 

      parent.Nodes.Add(child) 

      index += 1 

      AddMoreChildren(child) 
     End If 

    End Sub 

    Private Function GetLastAddedChildNode(ByVal parentNode As TreeNode, 
              ByVal level As Integer) As TreeNode 

     Dim newNode As New TreeNode 

     For Each node As TreeNode In parentNode.Nodes 
      If node.Level = level Then 
       newNode = node 
       Exit For 
      End If 
      newNode = GetLastAddedChildNode(node, level) 
     Next 

     Return newNode 

    End Function 

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 

     firstList.Add("S") 
     firstList.Add("A3") 
     firstList.Add("U13") 
     firstList.Add("ABC") 
     firstList.Add("PQ") 
     firstList.Add("1234") 

     secondList.Add("S") 
     secondList.Add("A3") 
     secondList.Add("U13") 
     secondList.Add("XYZ") 
     secondList.Add("ST") 
     secondList.Add("5478") 

     Dim root As TreeNode 
     mainList = firstList.Intersect(secondList).ToList() 
     root = New TreeNode(mainList.First) 

     index = 1 
     AddMoreChildren(root) 
     TreeView1.Nodes.Add(root) 

     Dim indexOfLastNode As Integer = mainList.Count - 1 

     If TreeView1.Nodes.Count = 1 Then 
      root = GetLastAddedChildNode(TreeView1.Nodes(0), indexOfLastNode) 

      mainList = firstList.Except(secondList).ToList() 
      If root.Text.Equals(firstList(indexOfLastNode)) Then 
       index = 0 
       AddMoreChildren(root) 

       mainList = secondList.Except(firstList).ToList() 
       index = 0 
       AddMoreChildren(root) 
      End If 
     End If 
    End Sub 

End Class 

Вот скриншот выхода:

enter image description here

+1

Привет Jinx88909, да. Это то, что мне нужно. но вместо 0,1, ... 5. и т. д. У меня есть тип API-объекта, который я бы заселял в древовидной структуре. Я также попробую ваш метод и дам вам знать, как это происходит. – DK2014

+0

спасибо, это тоже работает. только один запрос, как я могу добавить другой список с разными значениями, но один и тот же родительский в этом? Оба моих списка - это в основном два пути иерархии с общим TopNode. Эти списки могут иметь общие верхние 2-4 узла, после которых они расходятся. это возможно. С вашим кодом @Pro Grammer я могу получить оба пути в Treeview, но они кажутся отдельными. – DK2014

+1

@ DK2014 Если это также работает, вы должны щелкнуть стрелку вверх, чтобы UpVote. Upvotes помогают другим пользователям находить хорошие сообщения. – Plutonix

1

Соединенного этот код для вас:

Dim tmpNode As TreeNode = Nothing 

For Each num In myObjList.Reverse 
    Dim newNode = New TreeNode(num.ToString) 

    If tmpNode IsNot Nothing Then 
     newNode.Nodes.Add(tmpNode) 
    End If 

    tmpNode = newNode 
Next 

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

EDIT: А это один тоже не требует реверсирования списка

Dim topNode As TreeNode = Nothing 
Dim latestNode As TreeNode = Nothing 

For Each num In myObjList 
    Dim tmpNode = New TreeNode(num.ToString) 

    If myObjList.IndexOf(num) = 0 Then 
     topNode = tmpNode 
     latestNode = topNode 
    Else 
     latestNode.Nodes.Add(tmpNode) 
     latestNode = tmpNode 
    End If 
Next 
+0

Большое спасибо за быстрый ответ. в своем втором посте, можете ли вы сказать мне, что такое «числовой список»? или это «myObjList»? Кроме того, где указать имя Treeview? извините за основные вопросы. – DK2014

+0

Извините, я использовал временный список 'Dim numList = New List (Of Integer) From {0,1,2,3,4,5,6}'. Позвольте мне просто отредактировать это: P Что касается имени treeview, вы просто вызовите TreeView.Nodes.Add() и дадите ему то, что ваш 0 узел –

+0

отлично. Теперь он работает для меня. Еще один вопрос. если теперь у меня есть другой список, но с разными значениями, в то время как Topnode будет таким же (скажем, 0 в этом случае), могут ли они быть включены в одно дерево без дублирующих узлов? – DK2014

Смежные вопросы