I'm working on a Winform application, how can I check if there is a treeNode that its text is inside string Mystring? And how can i retrieve the tag of this node please?
if (myString.Contains(treeView1.Nodes.ToString()))
This works for only first matched node.
private TreeNode FindMatchedNode(TreeNodeCollection tnCol, string text)
{
TreeNode tn = null;
foreach (TreeNode node in tnCol)
{
if (text.ToLower().Contains(node.Text.ToLower()))
{
tn = node;
break;
}
else if (node.Nodes != null)
{
tn = FindNode(node.Nodes, text);
if (tn != null)
break;
}
}
return tn;
}
and for all matched nodes
private List<TreeNode> FindAllMatchedNodes(TreeNodeCollection tnCol, string text)
{
List<TreeNode> retVal = new List<TreeNode>();
foreach (TreeNode node in tnCol)
{
if (text.ToLower().Contains(node.Text.ToLower()))
{
retVal.Add(node);
}
else if (node.Nodes != null)
{
retVal.AddRange(FindNode(node.Nodes, text));
}
}
return retVal;
}
This method will traverse tree from root and find first node that Text is inside of myString
public object FindNode()
{
var queue = new Queue<TreeNode>();
foreach (var n in treeView1.Nodes)
{
// Add all root nodes to queue
queue.Enqueue(n);
}
while (queue.Count > 0)
{
// Take the next node from the front of the queue
var node = queue.Dequeue();
// Check if myString contains node text
if (myString.Contains(node.Text))
return node.Tag;
// Add the node’s children to the back of the queue
foreach (var child in node.Children)
{
queue.Enqueue(child);
}
}
// None of the nodes matched the specified string.
return null;
}
Related
I have TreeNode node.
something = treeview.Nodes[1].Nodes[4].Nodes[0];
TreeNode myNode = something;
And wish to know how pany parents it has and what indexes i need to use to find whole path out from this node.
I mean get "treeview.Nodes[1].Nodes[4].Nodes[0]" out from myNode
Something like this should work:
public IList<int> GetNodePathIndexes(TreeNode node)
{
List<int> indexes = new List<int>();
TreeNode currentNode = node;
while (currentNode != null)
{
TreeNode parentNode = currentNode.Parent;
if (parentNode != null)
indexes.Add(parentNode.Nodes.IndexOf(currentNode));
else
indexes.Add(currentNode.TreeView.Nodes.IndexOf(currentNode));
currentNode = parentNode;
}
indexes.Reverse();
return indexes;
}
You can then look at the result of this to get the indexes, and the count, to get the number of parents.
IList<int> path = GetNodePathIndexes(myNode);
StringBuilder fullPath = new StringBuilder("treeview");
foreach (int index in path)
{
fullPath.AppendFormat(".Nodes[{0}]", index);
}
Then fullPath.ToString() should return treeview.Nodes[1].Nodes[4].Nodes[0]
//...
string path = GetPath(treeView1.Nodes[0].Nodes[0].Nodes[1].Nodes[0]);
// now path is "treeView.Nodes[0].Nodes[0].Nodes[1].Nodes[0]"
//...
string GetPath(TreeNode node) {
int index;
Stack<string> stack = new Stack<string>();
while(node != null) {
if(node.Parent != null) {
index = node.Parent.Nodes.IndexOf(node);
stack.Push(string.Format("Nodes[{0}]", index));
}
else {
index = node.TreeView.Nodes.IndexOf(node);
stack.Push(string.Format("treeView.Nodes[{0}]", index));
}
node = node.Parent;
}
return string.Join(".", stack.ToArray());
}
This is the code which I am using, but I am always getting a blank string from the function.
How do I solve such a problem?
private string GetArrayofCheckedNodes()
{
string arrCheckedNodes = "";
ArrayList al = new ArrayList();
foreach (TreeNode node in TreeView1.Nodes)
{
if (node.Checked == true) // Checking whether a node is checked or not.
{
al.Add(node.Text);
}
}
for (int i = 0; i < al.Count; i++)
{
arrCheckedNodes += al[i].ToString() + " , ";
}
return arrCheckedNodes;
}
I'm assuming you want ALL checked nodes. TreeView1.Nodes only returns the first level so you will need to recurse down the tree. Also, you can use string.Join() to join the resultant values together.
private string GetArrayofCheckedNodes()
{
return string.Join(" , ", GetCheckedNodes(treeView1.Nodes));
}
public List<string> GetCheckedNodes(TreeNodeCollection nodes)
{
List<string> nodeList = new List<string>();
if (nodes == null)
{
return nodeList;
}
foreach (TreeNode childNode in nodes)
{
if (childNode.Checked)
{
nodeList.Add(childNode.Text);
}
nodeList.AddRange(GetCheckedNodes(childNode.Nodes));
}
return nodeList;
}
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 problem adding a childnode to specific node. Here is my code:
Method for painting tree
public void paint()
{
treeView1.Nodes.Clear();
TreeNode root = new TreeNode("Katalogas");
root.Name = "root";
treeView1.Nodes.Add(root);
foreach (string or in categories)
{
TreeNode subcat = new TreeNode(or);
subcat.Name = or;
root.Nodes.Add(subcat);
}
foreach (Preke or in PrekiuListas)
{
TreeNode subcat = new TreeNode(or.name);
subcat.Name = or.name;
TreeNode temp = FindNode(or.category);
temp.Nodes.Add(subcat);
}
Method for finding node
private TreeNode FindNode(String name)
{
foreach (TreeNode node in treeView1.Nodes[0].Nodes)
{
if (node.Nodes.Count > 0)
return FindNode(name);
if (node.Name == name)
return node;
}
return null;
}
I can add one child node to both nodes, but when i try to add another, i get stack overflow exception.. Please help, thanks
You have to pass the root node along with the method:
private TreeNode FindNode(String name, TreeNode root)
{
if(root.Name == name) return root;
Stack<TreeNode> nodes = new Stack<TreeNode>();
nodes.Push(root);
while(nodes.Count > 0)
{
var node = nodes.Pop();
foreach(TreeNode n in node.Nodes){
if (n.Name == name) return n;
nodes.Push(n);
}
}
return null;
}
//Usage
var node = FindNode(someName, treeView1.Nodes[0]);
//if your treeView has more root nodes, you have to loop through them
TreeNode node = null;
foreach(TreeNode node in treeView1.Nodes){
node = FindNode(someName, node);
if(node != null) break;
}
If the problem is just that of finding the node name, you can use the built-in TreeNodeCollection.Find() method for better performance:
public TreeNode[] Find(string key, bool searchAllChildren);
Example:
n.Nodes.Find("name", true);
The second parameter indicates that you want to search in all nodes recursively.
Also, this returns an entire TreeNode[] array, not a single node. So, you have to loop in them to fill or take the node[0] element if yo want to use just the first one.
I need to expand my treeview based on a fullpath in c#
My tree view has 2 nodes which are collapsed and I want to expand Node A to number 3
so I have the fullpath of node A\1\2\3.
How can I step through and open each node based of the fullpath? Also the length of the fullpath may change, so i may need to open node be to level 6. So it needs to be done based on the fullpath. Any help would be great.
Node A
1
2
3
Node B
1
2
3
4 5 6
This is what I've tried:
TreeNode [] n= treeView1.Nodes.Find(search, true);
if (n.Length > 0)
found = true;
treeView1.Nodes[t].Collapse();
foreach (TreeNode p in n) {
string[] a = p.FullPath.Split('\\');
foreach (string b in a) {
treeView1.SelectedNode = treeView1.Nodes[b];
treeView1.SelectedNode.Expand();
I'm sorry for not commenting on above answer given by S3ddi9 which is CORRECT. I'm only adding something.
So the answer given by S3ddi9
...
string path = #"A\1\2\";
var path_list = path.Split('\\').ToList();
foreach (TreeNode node in treeView1.Nodes)
if (node.Text == path_list[0])
ExpandMyLitleBoys(node, path_list);
}
private void ExpandMyLitleBoys(TreeNode node, List<string> path)
{
path.RemoveAt(0);
node.Expand();
if (path.Count == 0)
return;
foreach (TreeNode mynode in node.Nodes)
if (mynode.Text == path[0])
{
ExpandMyLitleBoys(mynode, path); //recursive call
break; //this was missing in earlier answer
}
}
Does work, BUT you must add a BREAK (I marked it), because if the for loop doesn't finish, return; won't return you to your main function and it will throw you an exception because path[0] is null.
I hope this will be more simpler, for Treeviews the best approach is to use recursive methods
...
string path = #"A\1\2\";
var path_list = path.Split('\\').ToList();
foreach (TreeNode node in treeView1.Nodes)
if (node.Text == path_list[0])
ExpandMyLitleBoys(node, path_list);
}
private void ExpandMyLitleBoys(TreeNode node, List<string> path)
{
path.RemoveAt(0);
node.Expand();
if (path.Count == 0)
return;
foreach (TreeNode mynode in node.Nodes)
if (mynode.Text == path[0])
ExpandMyLitleBoys(mynode, path); //recursive call
}
this does the work perfectly
Cracked it!!
TreeNode[] n = treeView1.Nodes.Find(search, true);
if (n.Length > 0)
found = true;
treeView1.Nodes[t].Collapse();
foreach (TreeNode p in n)
{
i = 0;
string[] a = p.FullPath.Split('\\');
foreach (string b in a)
{
if (i == 0)
{
treeView1.SelectedNode = treeView1.Nodes[b];
current = treeView1.Nodes[b];
treeView1.SelectedNode.Expand();
i = 1;
}
else
{
treeView1.SelectedNode = current.Nodes[b];
current = current.Nodes[b];
treeView1.SelectedNode.Expand();
if (b.ToUpper().Contains(search))
{
treeView1.SelectedNode.BackColor = System.Drawing.Color.Red;
}
I wrote a little simpler routine that works great. no recursion at all...
This assumes your path is a full file path like... "C:\program files\myapp" and when you add your nodes you set the node Key equal to the folder name
string[] strFolders = strPath.Split('\'));
System.Windows.Forms.TreeNode CurrentNode = null;
System.Windows.Forms.TreeNode[] FoundNodes = null;
foreach (string folder in strFolders) {
if (!folder.Contains(":")) {
if (CurrentNode == null) {
FoundNodes = treeFolders.Nodes.Find(folder, false);
} else {
FoundNodes = CurrentNode.Nodes.Find(folder, false);
}
if (FoundNodes.Length > 0) {
CurrentNode = FoundNodes[0];
CurrentNode.Expand();
} else {
//no folder found. cant continue
break;
}
}
}
if (CurrentNode != null) {
treeFolders.SelectedNode = CurrentNode;
}