我有一个包含以下字段的 SQL 表(称为 tblClosure):
- 位置 ID
- 位置描述
- 父母ID
我的问题是如何在 WinForms VB.NET 中填充TreeView
控件?DataTable
我在 C# 中看到过示例,但我是一名新手编码员,并且难以适应该代码。
任何帮助将不胜感激。
提前致谢
要查看我的答案的 C# 版本,请参阅这篇文章。
TreeView
要从aDataTable
或 any填充 a IEnumerable(Of T)
,您应该能够回答以下问题:
通过将上述问题的答案作为 lambda 表达式传递给以下方法,它使用递归算法创建一个列表TreeNode
,您可以将其添加到TreeView
. 每个都TreeNode
包含后代TreeNode
项目:
Private Iterator Function GetTreeNodes(Of T)(
ByVal source As IEnumerable(Of T),
ByVal isRoot As Func(Of T, Boolean),
ByVal getChilds As Func(Of T, IEnumerable(Of T), IEnumerable(Of T)),
ByVal getItem As Func(Of T, TreeNode)) As IEnumerable(Of TreeNode)
Dim roots As IEnumerable(Of T) = source.Where(Function(x) isRoot(x))
For Each root As T In roots
Yield ConvertEntityToTreeNode(root, source, getChilds, getItem)
Next
End Function
Private Function ConvertEntityToTreeNode(Of T)(
ByVal entity As T,
ByVal source As IEnumerable(Of T),
ByVal getChilds As Func(Of T, IEnumerable(Of T), IEnumerable(Of T)),
ByVal getItem As Func(Of T, TreeNode)) As TreeNode
Dim node As TreeNode = getItem(entity)
Dim childs = getChilds(entity, source)
For Each child As T In childs
node.Nodes.Add(ConvertEntityToTreeNode(child, source, getChilds, getItem))
Next
Return node
End Function
例子
我假设您已将数据加载到以下结构中:
Dim dt = New DataTable()
dt.Columns.Add("Id", GetType(Integer))
dt.Columns.Add("Name", GetType(String))
dt.Columns.Add("ParentId", GetType(Integer))
dt.Rows.Add(1, "Menu 1", DBNull.Value)
dt.Rows.Add(11, "Menu 1-1", 1)
dt.Rows.Add(111, "Menu 1-1-1", 11)
dt.Rows.Add(112, "Menu 1-1-2", 11)
dt.Rows.Add(12, "Menu 1-2", 1)
dt.Rows.Add(121, "Menu 1-2-1", 12)
dt.Rows.Add(122, "Menu 1-2-2", 12)
dt.Rows.Add(123, "Menu 1-2-3", 12)
dt.Rows.Add(124, "Menu 1-2-4", 12)
dt.Rows.Add(2, "Menu 2", DBNull.Value)
dt.Rows.Add(21, "Menu 2-1", 2)
dt.Rows.Add(211, "Menu 2-1-1", 21)
然后要将其转换为 a 的节点TreeView
,您可以使用以下代码:
Dim source = dt.AsEnumerable()
Dim nodes = GetTreeNodes(
source,
Function(r) r.Field(Of Integer?)("ParentId") Is Nothing,
Function(r, s) s.Where(Function(x) r("Id").Equals(x("ParentId")) ),
Function(r) New TreeNode With {.Text = r.Field(Of String)("Name")})
TreeView1.Nodes.AddRange(nodes.ToArray())
结果,您将拥有以下树结构:
├─ Menu 1
│ ├─ Menu 1-1
│ │ ├─ Menu 1-1-1
│ │ └─ Menu 1-1-2
│ └─ Menu 1-2
│ ├─ Menu 1-2-1
│ ├─ Menu 1-2-2
│ ├─ Menu 1-2-3
│ └─ Menu 1-2-4
└─ Menu 2
└─ Menu 2-1
└─ Menu 2-1-1
如果您有类似 2 级的数据层次结构,我建议您改用 gridview 控件并将其绑定到由这样的查询产生的数据表
Select
Case when ParentID>0 then ParentID else LocationID end as TheParentID
,LocationID
,LocationDesc
,ParentID
From tblClosure
Order by 0, ParentID, LocationDesc
然后根据 ParentID 的值,您可以设置不同的样式以显示它是父行还是子行。