Dynamic tree height

My tree image crashes when I upload it, so it has a size of about 100x150 pixels. When it is expanded, I want the treeview to display all the extended nodes.

To do this, the shape must increase as the tree grows, right? I am new to VB.net and I tried to find the "GrowOnly" property in treeview, but I could not find it ... Has anyone ever done this?

+4
source share
3 answers

AfterExpand / AfterCollapse event handling

Add AfterExpand and AfterCollapse event handlers for the tree to handle the reaction to expand / collapse nodes. I hard-coded the add-on for this example, but essentially it’s just the height of the menus, buttons, etc. That will be used to resize the form.

Private Sub Rapports_tvAllReports_AfterExpand(sender As Object, e As System.Windows.Forms.TreeViewEventArgs) Handles Rapports_tvAllReports.AfterExpand, Rapports_tvAllReports.AfterCollapse Dim Padding As Integer = 140 'Customize this, basically accounts for all buttons or menus included in the form which nests the treeview Dim TreeViewHeight As Integer = GetOpenedNodesRecursively(Rapports_tvAllReports) If formWindow = FormWindowState.Normal Then Me.Size = New Size(345, TreeViewHeight + Padding) End Sub 

All we do is increase Y and set a new Y in the form. To make treeview resize correctly with the shape, snap to the top and bottom .

Recursively pass through nodes

This function will go through the root nodes and call a recursive function on open nodes.

 Private Function GetOpenedNodesRecursively(ByVal aTreeView As TreeView) Dim Y As Integer = 0 'Go through each node of the treeview (first level) For Each n As TreeNode In aTreeView.Nodes Y += Rapports_tvAllReports.ItemHeight 'If the user expands a node, recursively increment the Y If n.IsExpanded Then Y += RecursiveYIncrement(n) Next Return Y End Function 

Now just continue to grow the TreeViewHeight with a recursive function that will return the height (Y) of all nodes that are expanding in the current tree view.

 Private Function RecursiveYIncrement(ByVal n As TreeNode) Dim Y As Integer = 0 'Go through each node of the treeview (first level) For Each aNode As TreeNode In n.Nodes Y += Rapports_tvAllReports.ItemHeight 'If the user expands a node, recursively increment the Y If aNode.IsExpanded Then Y += RecursiveYIncrement(aNode) Next Return Y End Function 

Visual reproduction

Here's what it looks like when we are done:

Let's start with a minimized tree view

Collapsed

Then we can expand some nodes and the shape will grow accordingly Expanded

And then we can again collapse the nodes and expand them, the form is again configured! Collapsed again

Forgive me for the French in the screenshots, this is the norm here in Quebec ... We must do this!

+2
source

You can capture BeforeExpand and AfterExpand TreeView Events to determine when the user changes the height of the node area. In this event handler, you need to find the bottom of the last node (using the Bounds property), then you will finally need to change the height of the form.

Ensure that the TreeView Anchor property includes both the top and the bottom so that it grows with the shape.

Of course, the shape should be taller than the TreeView. The bottom node Bounds.Bottom property will not be exactly the bottom of the tree, so my example below inflates it first with the height difference between the TreeView and the form, and then with the height difference of the TreeView client, and the overall height of the TreeView. It works correctly at my end.

You have assigned the same method to the BeforeExpand and AfterExpand . Note that it finds the last node by iterating through the nodes to find the bottom; you want to check to ensure that this is guaranteed to give you the last node.

EDIT: you need to tell the tree to scroll to display the first node before starting any of this so that it works sequentially: hence the call to EnsureVisible() .

 Private Sub TreeView1_BeforeOrAfterExpand(sender As Object, e As TreeViewEventArgs) Handles TreeView1.AfterExpand, TreeView1.AfterCollapse Dim lastNode As TreeNode = TreeView1.Nodes(0) TreeView1.Nodes(0).EnsureVisible() While lastNode.LastNode IsNot Nothing And lastNode.IsExpanded lastNode = lastNode.LastNode End While Dim diffBetweenFormAndTreeview As Integer = Me.Height - TreeView1.Height Dim diffBetweenTreeviewTotalAndClient As Integer = TreeView1.Height - TreeView1.ClientSize.Height Me.Height = lastNode.Bounds.Bottom + diffBetweenFormAndTreeview + diffBetweenTreeviewTotalAndClient End Sub 
0
source

The following extension function does the trick for both height and width. The tree itself is never transmitted, but only a set of nodes. See the example below.

 ''' <summary> ''' Measures the total height and width of all expanded tree nodes ''' </summary> ''' <param name="nodes">TreeNodeCollection which should be measured</param> ''' <returns> ''' Size structure representing the height and width of a rectangle formed from ''' the top-left of the first node in the collection, the right boundary of the ''' right-most expanded node, and the bottom boundary of the bottom-most ''' expanded node. ''' </returns> <System.Runtime.CompilerServices.Extension()> Public Function MeasureExpansion(nodes As TreeNodeCollection) As Size Dim size As New Size(0, 0) For Each node As TreeNode In nodes size.Height += node.Bounds.Height Dim newWidth As Integer = node.Bounds.Right If newWidth > size.Width Then size.Width = newWidth End If If node.IsExpanded Then Dim subNodeSize As Size = node.Nodes.MeasureExpansion() If subNodeSize.Width > size.Width Then size.Width = subNodeSize.Width End If size.Height += subNodeSize.Height End If Next Return size End Function 

An example call below. Notice that scrollbars are disabled in the sample tree tree. If you enable the scrollbar, you may need to resize the resulting size.

 tvDefinitions.Nodes.Clear() <treeview loaded here> tvDefinitions.ExpandAll() tvDefinitions.Size = tvDefinitions.Nodes.MeasureExpansion() 

Note that using AfterExpand / AfterCollapse events to trigger a tree resize does not work when there is only one node in the tree structure. The event does not fire.

0
source

All Articles