Checking parent if child checked - c#

i got this tree view and i made it to select all children if parent is checked, the way back as well. There's another rule to check some dependent child too. The problem is: I want to check the parent if any child is checked, but because those other rules i can't find a way to do that without the rules get conflict. So here's is the code i've made until now:
private void tvMorgan_AfterCheck(object sender, TreeViewEventArgs e)
{
//Check Children if parent checked
if (e.Node.Nodes.Count > 0)
{
TreeNode tnParent = e.Node;
if (tnParent.Checked)
{
foreach (TreeNode tnChild in tnParent.Nodes)
{
tnChild.Checked = true;
}
}
//Unchecked children if parent unchecked
else
{
foreach (TreeNode tnChild in tnParent.Nodes)
{
tnChild.Checked = false;
}
}
}
//If dependent node is selected, check the other two
else if (((e.Node.Text.Contains("BRL/EUR")) && (e.Node.Checked)) && (e.Node.Parent.Text.Contains("FWD")))
{
TreeNode tnParent = e.Node.Parent;
foreach (TreeNode tn in tnParent.Nodes)
{
if (tn.Text.Contains("BRL/USD") || tn.Text.Contains("EUR/USD"))
tn.Checked = true;
}
}
//If one of the two necessary nodes are uncheked, then uncheck the dependent one
else if ((((e.Node.Text.Contains("BRL/USD")) || (e.Node.Text.Contains("EUR/USD"))) && (!e.Node.Checked)) && (e.Node.Parent.Text.Contains("FWD")))
{
TreeNode tnParent = e.Node.Parent;
foreach (TreeNode tn in tnParent.Nodes)
{
if (tn.Text.Contains("BRL/EUR"))
tn.Checked = false;
}
}
}
Thanks in advance

The documentation of the TreeView.AfterCheck Event shows exactly how to do what you are looking for

Related

Validate node having same name in tree view at level zero

Tree
|
A-A1
-A2
|
B-B1
-B2
-B3
|
C-C1
-C2
private void treeView1_AfterLabelEdit(object sender, NodeLabelEditEventArgs e)
{
foreach (TreeNode tn in treeView1.Nodes)
{
if (!tn.Equals(e.Node) && tn.Text.ToUpper() == e.Label.ToUpper() )
{
MessageBox.Show("Name already available for parent. Cannot give same name.", "Rename element");
e.CancelEdit = true;
return;
}
}
string l_strOldDisplayName = treeView1.SelectedNode.Text;
this.BeginInvoke(new Action(() => RenameTreeElement(l_strOldDisplayName, e.Node)));
treeView1.LabelEdit = false;
treeView1.SelectedNode.EndEdit(false);
}
private void RenameElement(string f_strOldDisplayName, TreeNode updatedNode)
{
foreach (TreeNode currentNode in treeView1.Nodes)
{
if (currentNode.Level == 0)
{
if (updatedNode.Text == currentNode.Text)
{
MessageBox.Show("Name already available for parent. Cannot give same name.", "Rename element");
return;
}
}
}
}
I am renaming the tree node(A to B) at level 0 (A,B,C) but B is already present in treeview at that time i want to show message "Name already available for parent. Cannot give same name."
for that i have written above code but it is failed for when i give parent node name say 'A' to any child node in the tree it is not allowing..It should allow because parent name may be repeated in children
Updated code........
void treeView1_AfterLabelEdit(object sender, NodeLabelEditEventArgs e) {
foreach (TreeNode tn in treeView1.Nodes) {
if (!tn.Equals(e.Node) && tn.Text == e.Label&& !IsChildNodeHaveSameName(e.Label, e.Node)) {
MessageBox.Show("Name already in use.");
e.CancelEdit = true;
}
}
}
private bool IsChildNodeHaveSameName(string newName)
{//if new parent node name is under child node then skip
foreach (var node in Collect(treeView1.Nodes))
{
if (node.Text.ToUpper() == newName.ToUpper())
{
return true;
}
}
return false;
}
IEnumerable<TreeNode> Collect(TreeNodeCollection nodes)
{
foreach (TreeNode node in nodes)
{
yield return node;
foreach (var child in Collect(node.Nodes))
yield return child;
}
}
The e.Label property gives you the text that the user is writing in the floating label. With that, you can simplify your code into something like this:
void treeView1_AfterLabelEdit(object sender, NodeLabelEditEventArgs e) {
if (e.Node.Level == 0) {
foreach (TreeNode tn in treeView1.Nodes) {
if (!tn.Equals(e.Node) && tn.Text == e.Label) {
MessageBox.Show("Name already in use.");
e.CancelEdit = true;
}
}
}
}

asp.net treeview with folders and file from database

I have a requirement to bind folders and files to the treeview based on table data from data base, i tried lot of solution but failed to meet specific requirement.
Here is what im looking
Top folders
I have found one sample code and tried to achieve this
`
private void PopulateTreeview(DataTable dtFolders)
{
tvVendors.Nodes.Clear();
HierarchyTrees hierarchyTrees = new HierarchyTrees();
HierarchyTrees.HTree objHTree = null;
if (dtFolders.Rows.Count > 0)
{
foreach (DataRow dr in dtFolders.Rows)
{
objHTree = new HierarchyTrees.HTree();
objHTree.LevelDepth = int.Parse(dr["level"].ToString());
objHTree.NodeID = int.Parse(dr["folderid"].ToString());
objHTree.UnderParent = int.Parse(dr["parentid"].ToString());
objHTree.FIleName=dr["filename"].ToString();
objHTree.FilePath=dr["filepath"].ToString();
hierarchyTrees.Add(objHTree);
}
}
//Iterate through Collections.
foreach (HierarchyTrees.HTree hTree in hierarchyTrees)
{
//Filter the collection HierarchyTrees based on
//Iteration as per object Htree Parent ID
HierarchyTrees.HTree parentNode = hierarchyTrees.Find
(delegate(HierarchyTrees.HTree vendor)
{ return vendor.NodeID == hTree.UnderParent; });
//If parent node has child then populate the leaf node.
if (parentNode != null)
{
foreach (TreeNode tn in tvVendors.Nodes)
{
//If single child then match Node ID with Parent ID
if (tn.Value == parentNode.NodeID.ToString())
{
tn.ChildNodes.Add(new TreeNode
(hTree.NodeDescription.ToString(), hTree.NodeID.ToString()));
}
//If Node has multiple child ,
//recursively traverse through end child or leaf node.
if (tn.ChildNodes.Count > 0)
{
foreach (TreeNode ctn in tn.ChildNodes)
{
RecursiveChild(ctn, parentNode.NodeID.ToString(), hTree);
}
}
}
}
//Else add all Node at first level
else
{
tvVendors.Nodes.Add(new TreeNode
(hTree.NodeDescription, hTree.NodeID.ToString()));
}
}
tvVendors.ExpandAll();
}
public void RecursiveChild(TreeNode tn, string searchValue, HierarchyTrees.HTree hTree)
{
if (tn.Value == searchValue)
{
tn.ChildNodes.Add(new TreeNode
(hTree.NodeDescription.ToString(), hTree.NodeID.ToString()));
}
if (tn.ChildNodes.Count > 0)
{
foreach (TreeNode ctn in tn.ChildNodes)
{
RecursiveChild(ctn, searchValue, hTree);
}
}
}
Problem: I'm not able to bind file name to leaf node, if folder does not have any subfolder. bind the files. or if folder has subfolder and file both.bind both at same level. if folder is empty, it has nothing just bind it blank.
Could please test the code provide some solution`
foreach (TreeNode childnode in GetChildFolderNode(dataRow[ID].ToString(), table))
{
//Bind all folders
}
foreach (TreeNode childnode in GetChildFileNode(dataRow[ID].ToString(), table))
{
//bind all files
}

treeview how to expand a fullpath

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;
}

How to expand first level children only of Treeview

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();
}

how do I change the order of treenodes

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;
}

Categories