I have treenode & i would like to find the deepest child in the treenode.
if there are 2 child nodes with level 11 & level 13 respectively then i need unction to return me the value 13.
How can i do that ?
public int FindLevel(TreeNode oParentNode)
{
counter++;
forech(TreeNode oSubNode in oParentNode.Nodes)
{
FindLevel(oParentNode);
}
return Counter;
}
Here is my suggestion for you:
private int GetDeepestChildNodeLevel(TreeNode node)
{
var subLevel = node.Nodes.Cast<TreeNode>().Select(GetDeepestChildNodeLevel);
return subLevel.Count() == 0 ? 1 : subLevel.Max() + 1;
}
here with explicit types:
private int GetDeepestChildNodeLevel(TreeNode node)
{
var subLevel = node.Nodes.Cast<TreeNode>().Select<TreeNode, int>(subNode => GetDeepestChildNodeLevel(subNode));
return subLevel.Count<int>() == 0 ? 1 : subLevel.Max() + 1;
}
Here's the extension method for TreeView that returns Level of the deepest node in that TreeView.
public int GetDeepestNodeLevel(this System.Windows.Forms.TreeView treeView)
{
int level = -1;
foreach (System.Windows.Forms.TreeNode node in treeView.Nodes) {
int deep = DigInNodes(node);
if (deep > level)
level = deep;
}
return level;
}
private int DigInNodes(System.Windows.Forms.TreeNode node)
{
int level = node.Level;
foreach (System.Windows.Forms.TreeNode subnode in node.Nodes) {
int deep = DigInNodes(subnode);
if (deep > level)
level = deep;
}
return level;
}
Code is tested and works for me.
This is the fast way to get levelĀ“s deep of selected node.
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
TreeNode node = treeView1.SelectedNode;
MessageBox.Show(string.Format("You selected: {0}{1}", node.Text,e.Node.Level));
}
Related
been noodling around with BST's and I have a pretty good idea of them but I would like to be able to search for a particular node in the BST and have it tell me if it exists. I am using strings in the BST and everything seems to work well but I cannot figure out this Find method. If someone could tell me what I am doing wrong and how to fix it this would be appreciated.
class Node
{
public string number;
public string data;
public Node left;
public Node right;
public string Content;
public Node(string data)
{
this.data = data;
}
}
class BinarySearchTree
{
public Node root, current;
public BinarySearchTree()
{
this.root = null;
}
public void AddNode(string a) // code to insert nodes to the binary search tree
{
Node newNode = new Node(a); //create a new node
if (root == null) // if the tree is empty new node will be the root node
root = newNode;
else
{
Node previous;
current = root;
while (current != null)
{
previous = current;
if (a.CompareTo(current.data) < 1) //if the new node is less than the current node
{
current = current.left;
if (current == null)
previous.left = newNode;
}
else //if the new node is greater than the current node
{
current = current.right;
if (current == null)
previous.right = newNode;
}
}
}
}
public string FindNode(Node node, string s)
{
if (root == null)
return Output = "not found";
else if (s.CompareTo(root.data) < 1)
return FindNode(root.left, s);
else if (s.CompareTo(root.data) > 1)
return FindNode(root.right, s);
return Output = "found";
}
string SearchResult = "";
static string Output = "";
public string Display(Node rootNode)
{
if (rootNode != null)
{
Display(rootNode.left);
Output += rootNode.data;
Display(rootNode.right);
}
return Output;
}
}
private void btnExecute_Click(object sender, EventArgs e)
{
BinarySearchTree btree = new BinarySearchTree();
btree.AddNode("D");
btree.AddNode("B");
btree.AddNode("F");
btree.AddNode("E");
btree.AddNode("A");
btree.AddNode("G");
btree.AddNode("C");
string target;
txtOutput.Text += "The sorted values of the Binary Search Tree are: \r\n \r\n";
txtOutput.Text += btree.Display(btree.root);
txtOutput.Text += btree.FindNode(btree.root, "A");
}
Try to change the following:
1. Use CompareTo method with 0 not 1, so a.CompareTo(current.data) < 1 should be a.CompareTo(current.data) < 0
See documentation IComparable.CompareTo Method
2. As your FindNode is recursive call, change root to node usage
public string FindNode(Node node, string s)
{
if (node == null)
return Output = "not found";
else if (s.CompareTo(node.data) < 0)
return FindNode(node.left, s);
else if (s.CompareTo(node.data) > 0)
return FindNode(node.right, s);
return Output = "found";
}
Good luck!
I want to traverse through a treeview & set the value property to be its position in the tree as shown below
A[val:1]->A1[val:11]
l l--->A2[val:12]
l----->A3[val:13]
B[val:2]->B1[val:21]
l l--->B2[val:22]
C[val:3]->C1[val:31]
l l--->C2[val:32]
I have written a recursive which returns me all the nodes but i am unable to assign the desired position to its nodes.
private void TraverseTreeNode(TreeNodeCollection nodes)
{
foreach (TreeNode node in nodes)
{
TraverseTreeNode(node.ChildNodes);
}
}
Considering that TreeNode.Value is of type string, this will, starting at level = 1:
private static void TraverseTreeNode(TreeNodeCollection nodes, int parentNumber)
{
var childNumber = 1;
foreach (TreeNode node in nodes)
{
node.Value = string.Format("{0}{1}", parentNumber, childNumber ).Substring(0,node.Depth+1);
TraverseTreeNode(node.ChildNodes, parentNumber);
childNumber++;
if (node.Depth == 0) { parentNumber++; }
}
}
Only works for two levels but is easily extendable by adding additional parameters to TraverseTreeNode.
UPDATE
The following will work for any depth in hierarchy:
private static void TraverseTreeNode(TreeNodeCollection nodes, int parentNumber)
{
var childNumber = 1;
foreach (TreeNode node in nodes)
{
node.Value = node.Parent != null && node.Parent.Value != null
? string.Format("{0}{1}", node.Parent.Value, childNumber)
: string.Format("{0}{1}", parentNumber, childNumber).Substring(0, node.Depth + 1);
TraverseTreeNode(node.ChildNodes, parentNumber);
childNumber++;
if (node.Depth == 0) { parentNumber++; }
}
}
As you need recursive method, try this
private void Caller()
{
TraverseTreeNode(treeView1.Nodes);
}
private void TraverseTreeNode(TreeNodeCollection nodes)
{
int index = 1;
foreach (TreeNode node in nodes)
{
node.Text = (node.Parent != null ? node.Parent.Text : string.Empty) + index++;
TraverseTreeNode(node.Nodes);
}
}
I have a windows application in c# with a tree view .now i want to check all nodes of that tree view including node's of nodes .
i tried this code :
for (int i = 0; i < treevwaccess.Nodes.Count; i++)
{
formid = treevwaccess.Nodes[i].Name;
access = treevwaccess.Nodes[i].Checked;
user.updateaccesslevel(lblId.Text, formid, access);
}
but this code only check nodes in level 0
You have to use either a Stack or a recursive method like this:
DoStuff(treevwaccess.Nodes);
...
void DoStuff(TreeNodeCollection nodes)
{
foreach(TreeNode node in nodes)
{
user.updateaccesslevel(lblId.Text, node.Name, node.Checked);
DoStuff(node.Nodes);
}
}
You need to create and call recursive function like this
static void main()
{
var treevwaccess = new System.Windows.Forms.TreeView();
CheckAll(treevwaccess.Nodes);
}
static void CheckAll(System.Windows.Forms.TreeNodeCollection nodes )
{
foreach (System.Windows.Forms.TreeNode node in nodes)
{
var formid = node.Name;
var access = node.Checked;
user.updateaccesslevel(lblId.Text, formid, access);
CheckAll(node.Nodes);
}
}
You have to check child node of root node too.
For that please try this code.
for (int i = 0; i < treevwaccess.Nodes.Count; i++)
{
formid = treevwaccess.Nodes[i].Name;
access = treevwaccess.Nodes[i].Checked;
user.updateaccesslevel(lblId.Text, formid, access);
CheckChildNodes(treevwaccess.Nodes[i]);
}
void CheckChildNodes(TreeNode node)
{
if (node.Nodes.Count > 0)
{
for (int i = 0; i < node.Nodes.Count; i++)
{
formid = node.Nodes[i].Name;
access = node.Nodes[i].Checked;
user.updateaccesslevel(lblId.Text, formid, access);
}
}
}
This will help you.
I want to show all children of the first level on the treeview by default.
And then expand all children of those on click.
Try:
foreach (TreeNode tn in treeView1.Nodes) {
tn.Expand();
}
When adding nodes during runtime, you can just check the level and expand, if needed:
private void ShouldAutoExpand(TreeNode tn) {
if (tn.Level == 0)
tn.Expand();
}
There is no NodeAdded event you can hook into to check that automatically. You would have to determine yourself whether or not a node should be expanded "by default".
Update:
From your comment, it seems like you want to have all level 0 nodes expanded, but then expand all child nodes of level 1 when you expand them.
Try subscribing to the BeforeExpand event with this code:
private void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e) {
treeView1.BeforeExpand -= treeView1_BeforeExpand;
if (e.Node.Level == 1) {
e.Node.ExpandAll();
}
treeView1.BeforeExpand += treeView1_BeforeExpand;
}
you can try something like this.. you will have to change the example to fit your own code since you neglected to paste any code that you have or attempted
private void addChildNode_Click(object sender, EventArgs e)
{
var childNode = textBox1.Text.Trim();
if (!string.IsNullOrEmpty(childNode)) {
TreeNode parentNode = treeView2.SelectedNode ?? treeView2.Nodes[0];
if (parentNode != null) {
parentNode.Nodes.Add(childNode);
treeView2.ExpandAll();
}
}
}
if you want a recursive, try this:
void expAll(TreeNode node)
{
node.Expand();
foreach(TreeNode i in node.Nodes)
{
expAll(i);
}
}
private TreeNode ExpandUptoLevel(TreeNode tn,int level)
{
if (level != 0)
{
level --;
tn.Nodes[0].Expand();
return ExpandUptoLevel(tn.FirstNode, level);
}
return tn;
}
To expand all nodes in a tree to a level the above code does not work. Just add a check to read and compare the actual node level to the level that you wish to expand to. Here's a code snippet.
private void ExpandUptoLevel(TreeNode tn, int level)
{
if (level >= tn.Level)
{
tn.Expand();
foreach (TreeNode i in tn.Nodes)
{
ExpandUptoLevel(i,level);
}
}
}
Only to open the first nodes:
for (int i = 0; i< treeView1.Nodes.Count; i++)
{
treeView1.Nodes[i].Expand();
}
I would like to change the order of System.Windows.Forms.TreeNodes on the same level.
any suggestions on how this might be done in .net-2.0.
You need to manipulate the TreeView's Nodes collection. See TreeNodeCollection.
If you have three tree nodes and you want to move the last one to the front, for example: (Note: not tested code, but shows the idea)
var lastNode = MyTreeView.Nodes[2];
MyTreeView.Nodes.Remove(lastNode);
MyTreeView.Nodes.Insert(0, lastNode);
void MoveNodeUp(TreeNode node)
{
TreeNode parentNode = node.Parent;
int originalIndex = node.Index;
if (node.Index == 0) return;
TreeNode ClonedNode = (TreeNode)node.Clone();
node.Remove();
parentNode.Nodes.Insert(originalIndex - 1, ClonedNode);
parentNode.TreeView.SelectedNode = ClonedNode;
}
That's what I've written:
public void MoveNode(TreeView tv, TreeNode node, bool up)
{
if ((node.PrevNode == null) && up) {
return;
}
if ((node.NextNode == null) && !up) {
return;
}
int newIndex = up ? node.Index - 1 : node.Index + 1;
var nodes = tv.Nodes;
if (node.Parent != null) {
nodes = node.Parent.Nodes;
}
nodes.Remove(node);
nodes.Insert(newIndex, node);
}
I wrote this code which does not require any cloning.
For my case it moves up one position in the sibling nodes but can be adapted
TreeNode selectedNode = treeViewChain.SelectedNode;
if (selectedNode != null && selectedNode.Index > 0)
{
TreeNode parent = selectedNode.Parent;
int selectedIndex = selectedNode.Index;
selectedNode.Remove();
parent.Nodes.Insert(selectedIndex - 1, selectedNode);
treeViewChain.SelectedNode = selectedNode;
}