bulrick
asked on
Loading TreeView Recursively from Sql Database Tbl Vb.net
I am having problems loading a TreeView from an SQL DataTable. I managed to get the Save TreeView working.
I found some code in "C" that is supposed to work. You will notice it is included with comments.
I have convert the C code to Vb. I have checked the LoadTree subroutine and it seems to be working correctly.
I am having problems with the LoadRecursive Subroutine. I am relatively new to ADO.net so it may be
a small problem. Below is the structure of the database table I am loading the TreeView from.
Even though the code below is an eyefull the actual subroutine I am having trouble with is quite small.
I have been trying to get this to work for quite a while and cannot get it working correctly so far.
This may be easy for an expert... The points are high because I urgently need to get this resolved.
I would greatly appreciate help.
Thanks,
brad
'========================= ========== ========== ========== ========== ==
SQL Datatable TblTreeView1
fields
-------
TvNodeId Int
TvParentId Int
TvNodeName string
========================== ========== ========== ========== ========== =
' Sub LoadTree
========================== ========== ========== ========== ==========
' Following is the C Language version that I converted to Visual Basic
========================== ========== ========== ========== ==========
'
' private void LoadTree(TreeView tree)
' {
' // First of all, clear the tree to be sure, you might pass a TreeNode here to load your
'// tree into an existing TreeNode
'tree.Nodes.Clear();
' string sql = "select * from TREETABLE order by parent_id, node_id";
' //
' // Use a DataAdapter and DataSet here, I assume you have a DataSet named ds
' //
' foreach(DataRow row in ds.Tables["TREETABLE"].Row s)
' {
' int myId = Convert.ToInt32(row["node_ id"]);
' int parentId = Convert.ToInt32(row["paren t_id"]);
' string name = Convert.ToString(row["name "]);
' int permission = Convert.ToInt32(row["permi ssion"]);
' if( !CheckPermission(permissio n) )
' {
' // Not valid, current user has no permission to see this node, skip it...
' continue;
' }
' DataRow[] rootNodes = ds.Tables[0].Select("paren t_id = 0");
' foreach(DataRow row in rootNodes)
' {
' TreeNode node = new TreeNode(name);
' node.Tag = myId;
' tree.Nodes.Add(node);
' LoadRecursive(node, ds.Tables[0]);
' }
' }
' }
========================== ========== ========== ========== ==========
' Following is the Visual Basic Version of the code for LoadTree
========================== ========== ========== ========== ==========
Private Sub LoadTree()
' First of all, clear the tree to be sure, you might pass a TreeNode here to load your
' tree into an existing TreeNode
TreeView1.Nodes.Clear()
Dim ConnStr As String
ConnStr = ModMain.GpDcConnStr
Dim cn As New SqlClient.SqlConnection(Co nnStr)
Dim strSQL As String
strSQL = " SELECT * FROM tblTreeView1 "
strSQL += " ORDER BY TvParentId, TvNodeId;"
Dim ds As New DataSet
Dim da As New SqlClient.SqlDataAdapter(s trSQL, cn)
Dim tbl As New DataTable
da.Fill(tbl)
Dim dRow As DataRow
tbl.TableName = "Tv1"
Dim xMyId As Integer
Dim xParentId As Integer
Dim xNodeName As String
Dim xPermission As Integer
Dim xNode As New TreeNode
For Each dRow In tbl.Rows
xMyId = dRow("TvNodeId")
xParentId = dRow("TvParentId")
xNodeName = dRow("TvNodeName")
xPermission = dRow("TvPermission")
Call LoadRecursive(xParentId, tbl)
Next
End Sub
' ========================== ========== ========== ========== ========== == LoadRecursive
' ========================== ========== ========== ========== ========== =
' Following is the C Language source version of the code I converted to Vb.net
'
' private void LoadRecursive(TreeNode parentNode, DataTable table)
' {
' DataRow[] rows = table.Select("parent_id = " + ((int)parentNode.Tag));
' foreach(DataRow row in rows)
' {
' TreeNode node = new TreeNode((string)row["name "]);
' node.Tag = row["id"];
' parentNode.Nodes.Add(node) ;
' LoadRecursive(node, table);
' }
' }
========================== ========== ========== ==========
' Following is the Visual Basic Version
========================== ========== ========== ==========
Private Sub LoadRecursive(ByVal xParentNode As Integer, ByVal dt As DataTable)
Dim ConnStr As String
ConnStr = ModMain.GpDcConnStr
Dim cn As New SqlClient.SqlConnection(Co nnStr)
Dim strSQL As String
strSQL = " SELECT * FROM tblTreeView1 "
strSQL += " WHERE TvParentId = " & Str(xParentNode) & ";"
Dim da As New SqlClient.SqlDataAdapter(s trSQL, cn)
Dim ds As New DataSet()
da.Fill(Ds, "MyTreeView1")
cn.Close()
Dim xNodeId As TreeNode
Dim dRow As DataRow
For Each dRow In Ds.Tables("MyTreeView1").R ows
Dim xNodeName As New TreeNode(dRow("TvNodeName" ))
'xNode.Tag = dRow("TvNodeId")
xNodeId = dRow("TvNodeId")
TreeView1.SelectedNode.Nod es.Add(xNo deId)
xNodeId.Tag = xNodeId
LoadRecursive(xNodeId.Tag, dt)
Next
End Sub
I found some code in "C" that is supposed to work. You will notice it is included with comments.
I have convert the C code to Vb. I have checked the LoadTree subroutine and it seems to be working correctly.
I am having problems with the LoadRecursive Subroutine. I am relatively new to ADO.net so it may be
a small problem. Below is the structure of the database table I am loading the TreeView from.
Even though the code below is an eyefull the actual subroutine I am having trouble with is quite small.
I have been trying to get this to work for quite a while and cannot get it working correctly so far.
This may be easy for an expert... The points are high because I urgently need to get this resolved.
I would greatly appreciate help.
Thanks,
brad
'=========================
SQL Datatable TblTreeView1
fields
-------
TvNodeId Int
TvParentId Int
TvNodeName string
==========================
' Sub LoadTree
==========================
' Following is the C Language version that I converted to Visual Basic
==========================
'
' private void LoadTree(TreeView tree)
' {
' // First of all, clear the tree to be sure, you might pass a TreeNode here to load your
'// tree into an existing TreeNode
'tree.Nodes.Clear();
' string sql = "select * from TREETABLE order by parent_id, node_id";
' //
' // Use a DataAdapter and DataSet here, I assume you have a DataSet named ds
' //
' foreach(DataRow row in ds.Tables["TREETABLE"].Row
' {
' int myId = Convert.ToInt32(row["node_
' int parentId = Convert.ToInt32(row["paren
' string name = Convert.ToString(row["name
' int permission = Convert.ToInt32(row["permi
' if( !CheckPermission(permissio
' {
' // Not valid, current user has no permission to see this node, skip it...
' continue;
' }
' DataRow[] rootNodes = ds.Tables[0].Select("paren
' foreach(DataRow row in rootNodes)
' {
' TreeNode node = new TreeNode(name);
' node.Tag = myId;
' tree.Nodes.Add(node);
' LoadRecursive(node, ds.Tables[0]);
' }
' }
' }
==========================
' Following is the Visual Basic Version of the code for LoadTree
==========================
Private Sub LoadTree()
' First of all, clear the tree to be sure, you might pass a TreeNode here to load your
' tree into an existing TreeNode
TreeView1.Nodes.Clear()
Dim ConnStr As String
ConnStr = ModMain.GpDcConnStr
Dim cn As New SqlClient.SqlConnection(Co
Dim strSQL As String
strSQL = " SELECT * FROM tblTreeView1 "
strSQL += " ORDER BY TvParentId, TvNodeId;"
Dim ds As New DataSet
Dim da As New SqlClient.SqlDataAdapter(s
Dim tbl As New DataTable
da.Fill(tbl)
Dim dRow As DataRow
tbl.TableName = "Tv1"
Dim xMyId As Integer
Dim xParentId As Integer
Dim xNodeName As String
Dim xPermission As Integer
Dim xNode As New TreeNode
For Each dRow In tbl.Rows
xMyId = dRow("TvNodeId")
xParentId = dRow("TvParentId")
xNodeName = dRow("TvNodeName")
xPermission = dRow("TvPermission")
Call LoadRecursive(xParentId, tbl)
Next
End Sub
' ==========================
' ==========================
' Following is the C Language source version of the code I converted to Vb.net
'
' private void LoadRecursive(TreeNode parentNode, DataTable table)
' {
' DataRow[] rows = table.Select("parent_id = " + ((int)parentNode.Tag));
' foreach(DataRow row in rows)
' {
' TreeNode node = new TreeNode((string)row["name
' node.Tag = row["id"];
' parentNode.Nodes.Add(node)
' LoadRecursive(node, table);
' }
' }
==========================
' Following is the Visual Basic Version
==========================
Private Sub LoadRecursive(ByVal xParentNode As Integer, ByVal dt As DataTable)
Dim ConnStr As String
ConnStr = ModMain.GpDcConnStr
Dim cn As New SqlClient.SqlConnection(Co
Dim strSQL As String
strSQL = " SELECT * FROM tblTreeView1 "
strSQL += " WHERE TvParentId = " & Str(xParentNode) & ";"
Dim da As New SqlClient.SqlDataAdapter(s
Dim ds As New DataSet()
da.Fill(Ds, "MyTreeView1")
cn.Close()
Dim xNodeId As TreeNode
Dim dRow As DataRow
For Each dRow In Ds.Tables("MyTreeView1").R
Dim xNodeName As New TreeNode(dRow("TvNodeName"
'xNode.Tag = dRow("TvNodeId")
xNodeId = dRow("TvNodeId")
TreeView1.SelectedNode.Nod
xNodeId.Tag = xNodeId
LoadRecursive(xNodeId.Tag,
Next
End Sub
ASKER
Thank you for the help....
I haven't much time this morning.. meetings. However, quickly tried your solution and got a stack overflow in the following code.
The root node is zero... so I tried your code as is.
I got a stack overflow... it looks like its stuck in the loop below.
'------------------------- ---------- ---------- ---------- ---------- ---------- ---------- -----
For Each dRow In ds.Tables("MyTreeView1").R ows
xNodeText = dRow("TvNodeName").ToStrin g
xNodeID = dRow("TvNodeId")
If xParentNodeID = 0 Then
TreeView1.Nodes.Add(xNodeI D.ToString , xNodeText)
Else
TreeView1.Nodes(xParentNod eID.ToStri ng).Nodes. Add(xNodeI D.ToString , xNodeText)
End If
LoadRecursive(xNodeID)
Next
If xParentNodeID = 0 Then
TreeView1.Nodes.Add(xNodeI D.ToString , xNodeText)
Else
TreeView1.Nodes(xParentNod eID.ToStri ng).Nodes. Add(xNodeI D.ToString , xNodeText)
End If
'------------------------- ---------- ---------- ---------- ---------- ---------- ---------- --------
I will debug this more carefully and get back to you.
Do you see the problem?
My tree is Root
sub1
sub1a
sub 2
sub2A
-------------------------- ---------- ---------- ---------- ---------- --------
Data in tblTreeView1
TvNodeId TvParentId TvNodeName TvPermission (Permission is not used at this time)
0 0 Root 0
1 0 sub1 0
4 1 sub1a 0
2 0 sub2 0
3 2 sub2a 0
I haven't much time this morning.. meetings. However, quickly tried your solution and got a stack overflow in the following code.
The root node is zero... so I tried your code as is.
I got a stack overflow... it looks like its stuck in the loop below.
'-------------------------
For Each dRow In ds.Tables("MyTreeView1").R
xNodeText = dRow("TvNodeName").ToStrin
xNodeID = dRow("TvNodeId")
If xParentNodeID = 0 Then
TreeView1.Nodes.Add(xNodeI
Else
TreeView1.Nodes(xParentNod
End If
LoadRecursive(xNodeID)
Next
If xParentNodeID = 0 Then
TreeView1.Nodes.Add(xNodeI
Else
TreeView1.Nodes(xParentNod
End If
'-------------------------
I will debug this more carefully and get back to you.
Do you see the problem?
My tree is Root
sub1
sub1a
sub 2
sub2A
--------------------------
Data in tblTreeView1
TvNodeId TvParentId TvNodeName TvPermission (Permission is not used at this time)
0 0 Root 0
1 0 sub1 0
4 1 sub1a 0
2 0 sub2 0
3 2 sub2a 0
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Brilliant! I really appreciate this help. Have a great day!
Private Sub LoadRecursive(ByVal xParentNodeID As Integer)
Dim ConnStr As String
ConnStr = ModMain.GpDcConnStr
Dim cn As New SqlClient.SqlConnection(Co
Dim strSQL As String
strSQL = " SELECT * FROM tblTreeView1 "
strSQL += " WHERE TvParentId = " & Str(xParentNodeID) & ";"
Dim da As New SqlClient.SqlDataAdapter(s
Dim ds As New DataSet()
da.Fill(ds, "MyTreeView1")
cn.Close()
Dim dRow As DataRow
Dim xNodeText As String
Dim xNodeID As Integer
For Each dRow In ds.Tables("MyTreeView1").R
xNodeText = dRow("TvNodeName").ToStrin
xNodeID = dRow("TvNodeId")
If xParentNodeID = 0 Then
TreeView1.Nodes.Add(xNodeI
Else
TreeView1.Nodes(xParentNod
End If
LoadRecursive(xNodeID)
Next
End Sub
Then, change LoadTree() like this:
Private Sub LoadTree()
Treeview1.Nodes.Clear
LoadRecursive(0)
End Sub