I have tried every solution mentioned on these forums, with multiple variations, and the active node is still not highlighted (with background color) when the tree is loaded.
I set the tree data source to a dataset and expanded everything, this all works great.
I then tried several variations of the below, but the node is never highlighted.
var node = ultraTree1.GetNodeByKey("5"); ultraTree1.SelectedNodes.Clear(); node.BringIntoView(); ultraTree1.ActiveNode = node; ultraTree1.HideSelection = false; node.Selected = true;
The active node is correct and loads my list view with the related data. Even trying to override the back color didn't work. When I manually select the node, it highlights properly.
Hello Sam,
With the default implementation of the UltraTree, the tree needs to be the focused control to be able to see the active / selected node. You can override this by setting the following though:
this.ultraTree1.Override.ActiveNodeAppearance.BackColor = SystemColors.Highlight; this.ultraTree1.Override.ActiveNodeAppearance.ForeColor = Color.White;
Please let me know if you have any other questions or concerns on this matter.
Thanks for the response, but that did not work. Is there an execution order that matters? I tried various ones but nothing changes.
Is there a way to set the tree to the focused control on the form? I tried ultraTree1.Focus() but that did not help.
I have placed the code you have provided into my sample, and I was able to reproduce the behavior you are seeing. I believe the issue you are seeing here is due to 2 things:
1. I believe that trying to set the Active and Selected node right after you assign the data source is likely too early and you are hitting a timing issue between trying to set these things and when the tree has actually finished loading. I would recommend setting this in the Form’s Load event instead.
2. After checking the node that is returned by ultraTree.Nodes[5], I found that the Visible property of that node was false. This is probably due to the code that you have in the InitializeDataNode event for the UltraTree that is modifying the node visibility. I have changed the initial activation check to use the following, and everything is working as expected:
UltraTreeNode firstVisibleNode = null;
for (int i = 0; i < ultraTree1.Nodes.Count; i++) { UltraTreeNode node = ultraTree1.Nodes[i];
if (node.Visible) { firstVisibleNode = node; break; } }
if (firstVisibleNode != null) { ultraTree1.ActiveNode = firstVisibleNode; firstVisibleNode.Selected = true; }
Where did you add this new code? In ultraTree1_InitializeDataNode?
the only reason I was using InitializeDataNode is that if I don't, many of the folders are duplicated. Notice the highlighting is working if I don't use InitializeDataNode, but it's on one of the duplicated nodes. Am I doing something wrong that is causing this, or do I always have to use InitializeDataNode to keep it from happening?
I changed it to this, which fixed the duplication, but now the highlighting is gone again. The other reason for using InitializeDataNode was to set the Key value of the node, which is not set automatically when databound.
if (e.Node.IsRootLevelNode && e.Node.Cells["PID"].Value != DBNull.Value) { e.Node.Visible = false; return; }
I added the code in the Load event of the Form – as mentioned above, as if you are doing this right after assigning the data source to the tree, I believe you are hitting a timing issue where the tree has not actually finished loading yet.
Regarding the duplication, this is happening because of the DataRelation that you are defining:
DataRelation dr = new DataRelation("RR", folders.Columns["ID"], folders.Columns["PID"])
Since both the parent column and the child column of the DataRelation are in the same table, this creates a recursive, repeating layout in the UltraTree ‘n’ layers deep, where ‘n’ will be as long as the ID and PID of the current nodes match.
For example, taking the first node structure of A => E => F => G into account, this is happening because A is a parent-level tree node, but its ID matches the E node’s PID, and so E is a child of A. Following down this route, E has an ID of 5, which matches node F’s PID. Therefore, F is a child of E per your DataRelation. Finally, G is a child of F because G’s PID of 6 matches F’s ID of 6. The only reason it stops here is because there is no other entry in the “folders” DataTable with a PID that matches G’s ID of 7. If you are looking to prevent the current structure that is happening, I would recommend reviewing this table as you currently have a recursive, repeating DataRelation.
Thank you very much for all your help so far. We can stop here if you like. I just wanted to share an update.
When all the nodes are displayed using the existing data relation and no code to hide nodes in InitializeDataNode, it does highlight the correct folder. However, it's highlighting the last one in the collection, as you can see from the screenshot I posted earlier (pasted below). I guess because the keys are duplicated, it's returning the last one it finds, or maybe it's only looking at the parent nodes and not searching for all nodes at all levels, which would make sense, but I thought GetNodeByKey did a recursive search?
I guess if I need an exact node, I have to build a method to do a recursive search of visible nodes.
The GetNodeByKey method of the UltraTree is recursive, but it may not work as expected if the nodes have similar / equal keys as it expects a unique, case insensitive key to be passed.
If you have similar or equal keys for multiple nodes in the UltraTree, I would recommend doing a recursive search of the visible nodes, as you had mentioned.