Hi,
we are using the WinExplorerBar for grouping logical entities together in our Webshop backend application similar to MS-Outlook so there is one explorer bar group for Order Management, one for License Management, one for Configuration etc. Each of the groups contains a WinTree object where each node of the tree opens up appropriate view for the user. We've tried to set the optimal height of the explorer bar group by summing up the height of all currently expanded tree nodes, adding additional 5 pixels and that value is set with property ContainerHeight in ExplorerBarGroup.Settings. Every time a tree node is expanded or collapsed the total height required by the entire tree is calculated again, container height set again.
This all works perfectly fine but now we've a colleague who has set the Windows resolution to Medium - 125% and suddenly the size of the explorer bar group is too big which means that there is almost double space below the tree which is empty leading to a scrollbar for the group which wouldn't be necessary. I've investigated how the calculation changed, for each single node it required one additional pixel if set to 125% so for a total of 30 tree nodes this would require 30 pixels which is calculated correctly with my method. I've replaced the 5 pixels adding in my calculation to adding 30 pixels at the end, this shows the explorer bar nicely on the 125% resolution but then we have too much space in the 100% resolution!
Here is a code excerpt of the implementation. Method ResizeTree is called from the handler function for tree node expanded/collapsed.
/// <summary> /// Resizes the tree. /// </summary> /// <param name="tree">The tree.</param> private static void ResizeTree(UltraTree tree, UltraExplorerBarGroup explorerBarGroup) { int height = CalculateTreeHeight(tree); // Note: The value 5 has been replaced with 30 for the 125% resolution explorerBarGroup.Settings.ContainerHeight = height + 5; } /// <summary> /// Calculates the height of the tree. /// </summary> /// <param name="ultraTree">The akt ultra tree.</param> /// <returns>Returns the calculated tree height</returns> private static int CalculateTreeHeight(UltraTree ultraTree) { var retval = 0; AddNodeHeights(ultraTree.Nodes, ref retval); return retval; } /// <summary> /// Adds the node heights. /// </summary> /// <param name="nodes">The nodes.</param> /// <param name="sum">The sum.</param> private static void AddNodeHeights(TreeNodesCollection nodes, ref int sum) { if (nodes != null && nodes.Count > 0) { foreach (UltraTreeNode treeNode in nodes.Cast<UltraTreeNode>().Where(treeNode => treeNode.Visible && (treeNode.Parent == null || treeNode.Parent.Expanded))) { sum += treeNode.Bounds.Height; AddNodeHeights(treeNode.Nodes, ref sum); } } }
Just a guess but it sounds like you might be trying to access the UIElement property before the control has painted, at which time the property would indeed return null.
You can get around this by overriding the form's OnCreateControl method (deceptively named IMO, it actually coincides with the first time a control is painted), at which time the form and all child controls will have painted. Add your code after the call to base.OnCreateControl.
Also, the discrepancy between different resolutions is probably a consequence of the Form's AutoScaleMode defaulting to 'Font'. There is another setting, 'Dpi', which may solve your problem, but to be honest I vaguely remember this property being somewhat dysfunctional. I can't remember what the 'None' setting does, but you might want to try that.
Hi Hristo!
Thanks for your answer, I tried your input immediately but the UIElement property of all tree node objects is null thus the height of the explorer bar group is just the 5 pixels which are added after summing up everything.
Any ideas are welcome!
Thanks, Wolfgang
Hello,
When you change resolution of Windows it affect Font object (in general their size is in points which is relevant to the resolution). WindowsForms components are resized based on the font. Also Bounds property predates the addition of the control's ViewStyle property and It's not recommended to use this property when the UltraTree ViewStyle property is set. If you need correct calculation of the node height you could use UIElement if this node is visible, in this case your code should looks like:
private static void AddNodeHeights(TreeNodesCollection nodes, ref int sum) { if (nodes != null && nodes.Count > 0) { foreach (UltraTreeNode treeNode in nodes.Cast<UltraTreeNode>().Where(treeNode => treeNode.Visible && (treeNode.Parent == null || treeNode.Parent.Expanded))) { sum += (treeNode .UIElement != null ? treeNode.UIElement.Rect.Height : 0); AddNodeHeights(treeNode.Nodes, ref sum); } } }
Please let me know if you have any further questions.