I have a problem that I cannot seem to solve.
I am building a TreeView dynamically and I have an ordered list. I want the TreeView to build in such a way:
Node1
_Node2
__ Node3
__ _Node..N
My code is as follows:
TreeNode tn = new TreeNode();
for (int i = 0; i < EmployeesReportingLine.Count; i++ )
{
Employee ep = EmployeesReportingLine[i];
while (tn.ChildNodes.Count > 0)
tn = tn.ChildNodes[0];
TreeNode temp = new TreeNode(ep.FullName);
if (i > 0)
tn.ChildNodes.Add(temp);
else
tn = temp;
}
TreeView1.Nodes.Add(tn);
I have made several other attempts at using recursive functions but the snippet above was my best attempt.
Thanks in advance.
private void addNode(TreeNodeCollection nodes, TreeNode newnode) {
if (nodes.Count == 0) nodes.Add(newnode);
else addNode(nodes[0].Nodes, newnode);
}
Or:
private void addNode2(TreeNode start, TreeNode newnode) {
if (start.Nodes.Count == 0) start.Nodes.Add(newnode);
else addNode2(start.Nodes[0], newnode);
}
Related
I'm a beginner in C# and have a simple question about TreeView.
I want to do something like this:
> -Root
> -child1
> -child2
> -child3
> -....
I have this:
child.Text = des[j];
root.Nodes.Add(child);
But it just yields something like this:
> -Root
> -child1
I want:
To have a child of a child.
To create 10 TreeNodes in a for statement.
With different names like: root1, root2, root3, etc.
for (i = 0; i < 10; i++)
{
TreeNode root = new TreeNode();
}
You need to add the TreeNode to the Nodes collection of the child, not the root.
child.Text = des[j];
root.Nodes.Add(child);
TreeNode NextChild = new TreeNode();
NextChild.Text = "something";
child.Nodes.Add(NextChild);
For your second Question, you would need to store those treenodes in some kind of datastructure. If you want to name each one, a hashtable would be a good bet.
Hashtable myHT = new Hashtable();
for (int i = 0; i < 10; i++)
{
TreeNode root = new TreeNode();
myHT.Add("Root" + i, root);
}
You would then access them like,
TreeNode myRoot = (TreeNode)myHT["Root1"];
If you are comfortable with Generics you can use the System.Collections.Generic.Dictionary instead for a generic version.
You only need to keep track of the current node and the child to be inserted.
At i = 0, the current node value is the root node.
At i > 0, the current node value is the last child node inserted.
Then, you can try something like this...
TreeNode current = new TreeNode(); // Root node.
current.Text = string.Format("Root");
for (int i = 0; i < 10; i++)
{
TreeNode child = new TreeNode();
child.Text = string.Format("Child: {0}", i);
current.Nodes.Add(child);
current = child;
}
The result of this code will be:
Root
Child: 0
Child: 1
Child: 2
hi how i can set a image for my treeView nodes... I have a parent and a child node.
here is my code:
private void btnShowLicstate_Click(object sender, EventArgs e)
{
treeLic.Nodes.Clear();
string command = "\"C:\\lmxendutil.exe\" -licstatxml -host lwserv005 -port 6200";
string output = ExecuteCommand(command);
string final_output = output.Substring(90, output.Length - 90);
XmlReader xr = XmlReader.Create(new StringReader(final_output));
var xDoc = XDocument.Load(xr);
TreeNode root = new TreeNode();
LoadTree(xDoc.Root.Element("LICENSE_PATH"), root);
treeLic.Nodes.Add(root);
treeLic.ImageList = imageList1;
}
public void LoadTree(XElement root, TreeNode rootNode)
{
foreach (var e in root.Elements().Where(e => e.Attribute("NAME") != null))
{
var node = new TreeNode(e.Attribute("NAME").Value);
rootNode.Nodes.Add(node);
if (e.Name == "FEATURE")
{
node.SelectedImageIndex = 1;
}
else if (e.Name == "USER")
{
node.SelectedImageIndex = 0;
}
LoadTree(e, node);
}
}
my problem is that i have everyone the same picture but i want for FEATURE the index 1 and for USER the Index 2 but why it don't work ? :(
You should use ImageIndex property instead of SelectedImageIndex.
The first one is the index from ImageList for node in unselected state and the second one is applied when you select node using mouse, keyboard or through code.
I have one List type of my own struct.This is my struct.
public struct outlineData
{
public string paragraphID;
public string outlineText;
public int outlineLevel;
}
and my List is
List<outlineData> outlinePara = new List<outlineData>();
So, i have added so many outlineData in my outlinePara List.Now, i want to create a TreeView based on the outlineData's outlineLevel.
for example : outlineData's outlineLevel may be 0,1,2,3,1,2....0,1...0,1,1,1,1,1,2,3,2....
So, Now i want to create a Treeview like that...
0
1
2
3
1
2
0
1
0
1
1
1
1
1
2
3
2
TreeNode childNode;
if (outlineParaInfo.outlineLevel == 0)
{
headNode = new TreeNode(outlineParaInfo.outlineText);
TreeView11.Nodes.Add(headNode);
}
else if (outlineParaInfo.outlineLevel == 1)
{
childNode = new TreeNode(outlineParaInfo.outlineText);
headNode.ChildNodes.Add(childNode);
}
Please guide me to get a correct logic for this problem...
[EDITED TO USE System.Web.UI.WebControls.TreeView PER OP COMMENT]
How about something like the following pseudo code:
int currentLevel = 0;
TreeNode currentNode = null;
TreeNode childNode = null;
foreach(var outLineItem in outlinePara)
{
if(outLineItem.outlineLevel == 0)
{
currentNode = new TreeNode(
outLineItem.paragraphID, outLineItem.outlineText);
yourTreeView.Nodes.Add(currentNode);
continue;
}
if(outLineItem.outlineLevel > currentLevel)
{
childNode = new TreeNode(
outLineItem.paragraphID, outLineItem.outlineText);
currentNode.ChildNodes.Add(childNode);
currentNode = childNode;
currentLevel = outLineItem.outlineLevel;
continue;
}
if(outLineItem.outlineLevel < currentLevel)
{
currentNode = currentNode.Parent;
childNode = new TreeNode(
outLineItem.paragraphID, outLineItem.outlineText);
currentNode.ChildNodes.Add(childNode);
currentLevel = outLineItem.outlineLevel;
}
}
Like Antonio Bakula said, use parentParagraphID.
You can populate a treeview dynamically by using a recursive function
Change your outlineLevel with parentParagraphID.
public struct outlineData
{
public string paragraphID;
public string outlineText;
//public int outlineLevel;
public string parentParagraphID;
}
After creating your list.
List<outlineData> outlinePara = new List<outlineData>();
First insert the root TreeNode, then insert the rest.
TreeNode rNode = new rNode();
rNode.Name = "root";
outlinePara.Add(rNode);
...
outlinePara.Add(lastNode);
After inserting all the nodes, just launch this function.
populate(rNode, rNode.Name);
This function will create your level structure for your TreeView.
public void populate(TreeNode node, string parentParID)
{
var newList = this.outlinePara.Where(x => x.parentParagraphID == parentParID).toList();
foreach(var x in newList)
{
TreeNode child = new TreeNode();
child.Name = paragraphID;
child.Text = outlineText;
populate(child, child.Name);
node.Nodes.Add(child);
}
}
You will get a TreeView like this
root
|-->0
| |-->1
| |-->1
| |-->2
| |-->2
| |-->2
|
|-->0
| |-->1
| ...
...
Tip
In this code the ID is a string, it's much better to use something else, and it has to be unique, so you won't get a problem with your data placed in another parentNode.
private void generateTreeView()
{
int currentLevel = 0;
TreeNode currentNode = null;
TreeNode childNode = null;
foreach (var outLineItem in outlineParagraph)
{
if (outLineItem.outlineLevel == 0)
{
currentNode = new TreeNode(outLineItem.outlineText);
TreeView11.Nodes.Add(currentNode);
currentLevel = outLineItem.outlineLevel;
continue;
}
if (outLineItem.outlineLevel > currentLevel)
{
childNode = new TreeNode(outLineItem.outlineText);
currentNode.ChildNodes.Add(childNode);
currentNode = childNode;
currentLevel = outLineItem.outlineLevel;
continue;
}
if (outLineItem.outlineLevel < currentLevel)
{
//logic to find exact outlineLevel parent...
currentNode = findOutlineLevelParent(outLineItem.outlineLevel, currentNode);
if(currentNode!=null)
currentNode = currentNode.Parent;
childNode = new TreeNode(outLineItem.outlineText);
currentNode.ChildNodes.Add(childNode);
currentLevel = outLineItem.outlineLevel;
currentNode = childNode;
continue;
}
if (outLineItem.outlineLevel == currentLevel)
{
currentNode = currentNode.Parent;
childNode = new TreeNode(outLineItem.outlineText);
currentNode.ChildNodes.Add(childNode);
currentLevel = outLineItem.outlineLevel;
currentNode = childNode;
continue;
}
}
}//generateTreeView Ends here...
private TreeNode findOutlineLevelParent(int targetLevel, TreeNode currentNode)
{
while (currentNode.Parent != null)
{
currentNode = currentNode.Parent;
if (currentNode.Depth == targetLevel)
{
return currentNode;
}
}
return null;
} //findOutlineLevelParent ends here...
I have a TreeView in my Windows application. Tn this TreeView, the user can add some root nodes and also some sub nodes for these root nodes and also some sub nodes for these sub nodes and so on ...
For example:
Root1
A
B
C
D
E
Root2
F
G
.
.
.
Now my question is that if I am at node 'E' what is the best way to find its first root node ('Root1')?
Here is a little method for you:
private TreeNode FindRootNode(TreeNode treeNode)
{
while (treeNode.Parent != null)
{
treeNode = treeNode.Parent;
}
return treeNode;
}
you can call in your code like this:
var rootNode = FindRootNode(currentTreeNode);
public TreeNode RootTreeNode(TreeNode n) { while (n.Level > 0) { n = n.Parent; } return n; }
Example to get root treenode:
private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
var node = (e == null ? ((System.Windows.Forms.TreeView)sender).SelectedNode : e.Node);
var rootNode = RootTreeNode(node);
}
Enjoy
I am trying to construct a TreeView from a Menu. My Code is like this:
public class MenuExtractionUtility
{
public TreeView MenuTraverse(MainMenu mainMenu)
{
TreeView treeView = new TreeView();
TreeNode mainNode = new TreeNode();
foreach (MenuItem mi in mainMenu.MenuItems)
{
System.Diagnostics.Debug.WriteLine(mi.Text);
mainNode.Text = mi.Text;
TreeNode tn = MenuItemTraverse(mi);
mainNode.Nodes.Add(tn);
}
treeView.Nodes.Add(mainNode);
return treeView;
}
private TreeNode MenuItemTraverse(MenuItem menuItem)
{
TreeNode treeNode = new TreeNode();
foreach(MenuItem mi in menuItem.MenuItems)
{
System.Diagnostics.Debug.WriteLine(mi.Text);
treeNode.Text = mi.Text;
TreeNode tr = MenuItemTraverse(mi);
if (tr!=null && tr.Text != "")
{
treeNode.Nodes.Add(tr);
}
}
return treeNode;
}
}
But this is not working.
What can be the problem?
I think there are two problems in the methods. Let's start with the MenuItemTraverse method. You get a MenuItem as input. You declare a TreeNode variable, and assign a new TreeNode instance to it. Then you loop over the menu item's sub items. For each iteration you assign the text from the sub item to the TreeNode (I would assume that you would want the text of the incoming menu item on this TreeNode). To get the intended behaviour you should remove this line from the loop:
treeNode.Text = mi.Text;
...and add this line before the loop:
treeNode.Text = menuItem.Text;
It looks like you have the exact same problem in the MenuTraverse method, so do the same change there. I think that would solve it for you (didn't test the code yet; might have missed something).
Update
I gave it a bit of though, since I felt that the code could probably be simplified a bit, and this is what I came up with. Instead of having two different methods for MainMenu and MenuItem input, this one encapsulates the process into one single method. Also, it takes a TreeNodeCollection, which means that you can have the method inject the menu structure into an already existing (and populated) TreeView control, at any level in the tree.
public class MenuExtractionUtility
{
public static void MenuItemTraverse(TreeNodeCollection parentCollection, Menu.MenuItemCollection menuItems)
{
foreach (MenuItem mi in menuItems)
{
System.Diagnostics.Debug.WriteLine(mi.Text);
TreeNode menuItemNode = parentCollection.Add(mi.Text);
if (mi.MenuItems.Count > 0)
{
MenuItemTraverse(menuItemNode.Nodes, mi.MenuItems);
}
}
}
}
Usage example:
treeView1.Nodes.Clear();
MenuExtractionUtility.MenuItemTraverse(treeView1.Nodes, mainMenu1.MenuItems);
This code was just quickly put together, so you may want to "stabilize" it a bit by adding null checks and similar.
here it is...
public class MenuExtractionUtility
{
public void MenuTraverse(MainMenu mainMenu, TreeView treeView)
{
TreeNode ultimateMainNode = new TreeNode();
ultimateMainNode.Text = "Root";
TreeNode mainNode = null;
foreach (MenuItem mi in mainMenu.MenuItems)
{
if (mi != null && mi.Text != "")
{
mainNode = null;
if (mi.MenuItems.Count <= 0)
{
mainNode = new TreeNode();
mainNode.Text = mi.Text;
}
else if (mi.MenuItems.Count > 0)
{
mainNode = MenuItemTraverse(mi);
}
ultimateMainNode.Nodes.Add(mainNode);
}
}
treeView.Nodes.Add(ultimateMainNode);
}
private TreeNode MenuItemTraverse(MenuItem menuItem)
{
TreeNode treeNode = new TreeNode();
System.Diagnostics.Debug.Write(menuItem.Text+",");
treeNode.Text = menuItem.Text;
foreach (MenuItem mi in menuItem.MenuItems)
{
if (mi != null && mi.Text != "")
{
TreeNode tr = MenuItemTraverse(mi);
if (tr != null && tr.Text != "")
{
treeNode.Nodes.Add(tr);
}
}
}
return treeNode;
}