By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,112 Members | 1,642 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,112 IT Pros & Developers. It's quick & easy.

Last try at this treeview

P: n/a
I had given up on this for a while, but I am attempting it again.

This is what i am using to store my treeview layout into a db, I
am only using a few fields to make it easier to understand while
I am attempting to restore it back into the tree.

Text "Parent0", Level 0
Text "Child0", Level 1
Text "SubChild0", Level 2

Now I have read many posts where others are saying to store a unique
id
of the parent. I am having a bit of trouble trying to store an id
somewhere
and retrieve it on the next loop.

This is what I am looking at in the debugger, I am looking for
something that
I can use that is unique. This is a multilayer, many roots and many
nested nodes
in the treeview. This is just a sample I am posting.

//-------------------- Debugger values ------------------------------
+ Parent null System.Windows.Forms.TreeNode
Text "Parent0" string
Level 0 int
+ FirstNode {Text = "Child0"} System.Windows.Forms.TreeNode
+ NextNode {Text = "Parent1"} System.Windows.Forms.TreeNode
+ NextVisibleNode {Text = "Child0"} System.Windows.Forms.TreeNode

+ Parent {Text = "Parent0"} System.Windows.Forms.TreeNode
Text "Child0" string
Level 1 int
+ FirstNode {Text = "SubChild0"} System.Windows.Forms.TreeNode
+ NextNode null System.Windows.Forms.TreeNode
+ NextVisibleNode {Text = "SubChild0"} System.Windows.Forms.TreeNode

+ Parent {Text = "Child0"} System.Windows.Forms.TreeNode
Text "SubChild0" string
Level 2 int
+ FirstNode {Text = "SubSubChild0"} System.Windows.Forms.TreeNode
+ NextNode null System.Windows.Forms.TreeNode
+ NextVisibleNode {Text = "SubSubChild0"}
System.Windows.Forms.TreeNode

//-------------------- Debugger values ------------------------------

Lets say I start the loop, my first node will be "Parent0" it does not
have a parent, its a
rootnode, the ParentID for this will be NULL. On th next round I come
up with "Child0"
and that node has a parent which is "Parent0". Now how would I
generate a GUID for
Parent0, and tell Child0 who its parent is? Even if I create an
instance of my struct and store
the information in the struct. That information will be lost on my
next round of the loop because
I have to create a new instance of the struct again.

I am pretty confused right now, maybe I am over analyzing everything
and thats why i cant
get anything to work. Here is some sample code that leads to nowhere.
SaveTreeViewRecords SaveRecords = new
SaveTreeViewRecords();
foreach (TreeNode node in TreeView1.Nodes)
{
SaveRecords.SaveDBRecords(node);
}

class SaveTreeViewRecords
{
public void SaveDBRecords(TreeNode node)
{
// create dataset connections here

String parentID = Guid.NewGuid().ToString();
String nodeText = node.Text;
int nodeLevel = node.Level;

// store information to db here

foreach (TreeNode childNode in node.Nodes)
{
SaveDBRecords(childNode);
}
}
}

My class is longer than that, but I just want to keep this simple
since I am confused already.

This is what my sample tree look like until I can get this thing
working.

for (int x = 0; x < 2; ++x)
{
TreeNode ParentNode = tvMain.Nodes.Add("Parent" +
x.ToString());
TreeNode ChildNode = ParentNode.Nodes.Add("Child" +
x.ToString());
TreeNode SubChildNode = ChildNode.Nodes.Add("SubChild"
+ x.ToString());
TreeNode SubSubChildNode =
SubChildNode.Nodes.Add("SubSubChild" + x.ToString());
}

Once I can get the storing of the information to the DB, then I can
worry about loading it back
in. But thats another headache I am not eady to tackle just yet.

Thanks

John

Jan 7 '08 #1
Share this Question
Share on Google+
7 Replies


P: n/a
On Sun, 06 Jan 2008 17:29:14 -0800, John Rogers <jo************@aol.com>
wrote:
[...]
Lets say I start the loop, my first node will be "Parent0" it does not
have a parent, its a
rootnode, the ParentID for this will be NULL. On th next round I come
up with "Child0"
and that node has a parent which is "Parent0". Now how would I
generate a GUID for
Parent0, and tell Child0 who its parent is?
You don't need to tell Child0 who its parent is, but even if you did it's
as easy as doing so in the loop where you enumerate the children of the
parent.

In your own example, I think the main thing you need to do is add a
parameter to the SaveDBRecords() method that takes the Guid you created.
Pass null for the parameter at the top level, and then pass the parent
Guid when looping for each child. The parent Guid would be written along
with the rest of each node's information (handling null as appropriate to
your database, of course). Of course, the node's information should
include its own Guid as well, so for each node record you'll be writing
two Guids.

I should say: you don't seem all that familiar with recursion, and you've
picked a somewhat challenging task with which to introduce yourself to
recursion. You might want to review some more basic examples and try to
become more comfortable with recursive algorithms before trying to get
this one done. It might make your life easier.

Pete
Jan 7 '08 #2

P: n/a
Thanks for the tip Pete.
"Peter Duniho" <Np*********@nnowslpianmk.comwrote in message
news:op***************@petes-computer.local...
On Sun, 06 Jan 2008 17:29:14 -0800, John Rogers
<jo************@aol.com wrote:
I should say: you don't seem all that familiar with recursion, and
you've picked a somewhat challenging task with which to introduce
yourself to
Actually I hate recursion. Even when I coded in c++builder I always
had problems with
recursion. Just as you are helping me here, it was the same there,
others helped me out
until I got the hang of it.

But really, the treeview is really the only control that I have
problems with. It takes a lot
of though on how to handle the recursion. I actually do have it
working, its just a matter
of writing a guid for each record which is not a problem. But i was
thinking too technical
and that causes me more problems than I would normally have.

I will implement what you said and see how much further I can get with
the tree structure.
John
Jan 7 '08 #3

P: n/a
bob

On Sun, 6 Jan 2008 19:29:14 -0600, "John Rogers"
<jo************@aol.comwrote:
>I had given up on this for a while, but I am attempting it again.

This is what i am using to store my treeview layout into a db, I
am only using a few fields to make it easier to understand while
I am attempting to restore it back into the tree.

Text "Parent0", Level 0
Text "Child0", Level 1
Text "SubChild0", Level 2
<Stuff Deleted>

Hi John,
How about deriving a class from treenode that has a 'NodeId' and a
'PrevNodeId' property.

Also have a int that can provide a sequence of Ids during the
creation phase.

Everytime you create a node you assign the next value of the int to
the NodeId.
I take it your business logic decides who the parent is of any node.
This logic assigns the PrevNodeId field.

Roots are detectable because their PrevNodeId is 0
hth
Bob
Jan 7 '08 #4

P: n/a
just to get in the mood for recursion,
try to realize your problem/function in haskel first,
http://en.wikipedia.org/wiki/Haskell...mming_language)
then look for syntax problems... with is the compilers job ;)
//CY
Jan 7 '08 #5

P: n/a
bob
On Sun, 6 Jan 2008 22:53:23 -0600, "John Rogers"
<jo************@aol.comwrote:
>Hi John,
How about deriving a class from treenode that has a 'NodeId' and a
'PrevNodeId' property.

Hi Bob,

Thats exactly what I have. I thought I had it figured out a little
while ago, but when I
changed the structure of the tree, I realized that I am still lost.
This is my code so far.
<Stuff Deleted>

Hi John,
Had a bit of play with your code.
I think the problem is more a conceptual one rather than a coding one.
You are creating and placing the nodes on the tree then trying to set
the node ids etc as you are writing to the database.

The following snippet shows what I was getting at;
1) Create nodes and add them to a collection (Don't try and place
them)
2) Use business logic to derive the ParentID for each node in the
collection (Ok I have simulated the business logic in the node
creation but you could iterate through the collection doing the same
thing)

3) Use a recursive routine to place the nodes on the tree.

This also simplifies the database side.
You write the collection to the database.
You retrieve the collection from the database and feed it to the
Placenodes routine.

There are probably more elegant ways of doing this but
it works...
Code follow for;
Form
clsMyTreeNode

hth

Bob
P.S. Don't forget you can hang objects on the tag property of the
treenodes (allowing full separation of the data from the tree
structure) i.e. Database tree table and linked DataTables that provide
the Data.
****Form Code***
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
myCol = new List<clsMyTreeNode>();
}
private IEnumerable<clsMyTreeNodemyCol;
private void button1_Click(object sender, EventArgs e)
{
//treeView1.BeginUpdate();
treeView1.Nodes.Clear();
for (int x = 1; x < 7; ++x)
{
clsMyTreeNode node = MakeNode(x);
((List<clsMyTreeNode>)myCol).Add(node);
}
//treeView1.ExpandAll();
//treeView1.EndUpdate();
MessageBox.Show("Nodes Made");

}
clsMyTreeNode MakeNode(int x)
{
clsMyTreeNode node = new clsMyTreeNode(x);
switch(x)//'Business Logic' Simulation
{
case 1://root node
break;
case 2:
node.ParentNodeId = 1;
break;
case 3:
node.ParentNodeId = 2;
break;
case 4://root node
break;
case 5:
node.ParentNodeId = 4;
break;
case 6:
node.ParentNodeId = 5;
break;
}
return node;
}

private void button2_Click(object sender, EventArgs e)
{
clsMyTreeNode root = new clsMyTreeNode(0);
this.treeView1.Nodes.Add((TreeNode)root);
PlaceNodes(ref root,(List<clsMyTreeNode>)myCol);
this.treeView1.Refresh();
}
void PlaceNodes(ref clsMyTreeNode root,List<clsMyTreeNode>
nodes)
{
try
{
bool lglPlaced = false;
for (; !lglPlaced; )
{
lglPlaced = true;
foreach (clsMyTreeNode c in nodes)
{
if (!c.Placed)
{

// Place node and set status

CallRecursive(((clsMyTreeNode)(root)), c);

// debug.Writeline("CallRecursive " &
c.Text & " " & "Status " & c.Status.ToString)
}
}
foreach (clsMyTreeNode c in nodes)//if nodes not
placed around we go again
{
if (!c.Placed)
{
lglPlaced = false;
}
}
}
}
catch (Exception ex)
{

MessageBox.Show("PlaceNodes " + ex.Message);
}
}
private void CallRecursive(clsMyTreeNode Location,
clsMyTreeNode placement) {
// Called by LoadTree
// Depth First traversal of tree, placing nodes and setting
statuses
//clsMyTreeNode n;
try {
if (placement.Placed) {
return;
}
foreach (clsMyTreeNode n in Location.Nodes) {
// PlaceIt(n, placement)
if (placement.Placed) {return;}
CallRecursive(n, placement);
//return;

}
//Debug.Assert((placement.NodeId 0));
if (((Location.NodeId == placement.ParentNodeId)
&& !placement.Placed)) {
// Ready to place
//placement.Text = placement.Name;
Location.Nodes.Add(placement);
placement.Placed = true;

}
}
catch (ApplicationException ex) {
MessageBox.Show("CallRecursive " + ex.Message);
}
}

}
}
*****Derived Treenode Class *******
class clsMyTreeNode:TreeNode
{

public clsMyTreeNode()
{

}
public clsMyTreeNode(int iNodeId)
{

myNodeId = iNodeId;
myParentNodeId = 0;

}
private int myParentNodeId;
public int ParentNodeId
{
get { return myParentNodeId; }
set { myParentNodeId = value; }
}
private int myNodeId;

public int NodeId
{
get { return myNodeId; }
set { myNodeId = value; }
}
public override string ToString()
{
return "MyId is " + myNodeId + "Parent is " +
myParentNodeId;
}
private bool mlPlaced;

public bool Placed
{
get { return mlPlaced; }
set { mlPlaced = value;
this.Text = "MyId is " + myNodeId + "Parent is " +
myParentNodeId;
}
public override object Clone()
{
clsMyTreeNode clone = (clsMyTreeNode)base.Clone();
clone.NodeId = this.NodeId;
clone.ParentNodeId = this.ParentNodeId;
return clone;
}

}
Jan 8 '08 #6

P: n/a

"bob" <st**************@cutthis.adriley.co.nzwrote in message
news:gd********************************@4ax.com...
On Sun, 6 Jan 2008 22:53:23 -0600, "John Rogers"
<jo************@aol.comwrote:

Hi John,
Had a bit of play with your code.
I think the problem is more a conceptual one rather than a coding
one.
You are creating and placing the nodes on the tree then trying to
set
the node ids etc as you are writing to the database.

The following snippet shows what I was getting at;
Thanks for the help Bob, I really do appreciate you helping me like
this.
Not being a professional programmer or writing code for a living makes
it difficult at times when you want to write something. But thank God
for
the internet and for helpful people who help each other.

Thanks again.

John
Jan 9 '08 #7

P: n/a
bob
On Tue, 8 Jan 2008 18:07:19 -0600, "John Rogers"
<jo************@aol.comwrote:
>
"bob" <st**************@cutthis.adriley.co.nzwrote in message
news:gd********************************@4ax.com.. .
>On Sun, 6 Jan 2008 22:53:23 -0600, "John Rogers"
<jo************@aol.comwrote:

Hi John,
Had a bit of play with your code.
I think the problem is more a conceptual one rather than a coding
one.
You are creating and placing the nodes on the tree then trying to
set
the node ids etc as you are writing to the database.

The following snippet shows what I was getting at;

Thanks for the help Bob, I really do appreciate you helping me like
this.
Not being a professional programmer or writing code for a living makes
it difficult at times when you want to write something. But thank God
for
the internet and for helpful people who help each other.

Thanks again.

John
Your Welcome
regards
bob
Jan 10 '08 #8

This discussion thread is closed

Replies have been disabled for this discussion.