/// <summary> /// Arrange the children in the panel using the calculations from measure pass. /// </summary> /// <param name="finalSize">Total area available to arrange the controls</param> /// <returns>Total used area</returns> protected override System.Windows.Size ArrangeOverride(System.Windows.Size finalSize) { double closedExpandersTotalHeight = 0; // Total minimum height required by closed expanders and expanders with user defined height. double openExpandersTotalHeight = 0; // Total size asked by all open expanders foreach (UIElement child in this.Children) { Expander childExpander = child as Expander; if (childExpander != null) { // Get a height if user has resized double?userHeight = (double?)childExpander.GetValue(UserDefinedSizeProperty); if (userHeight != null) { closedExpandersTotalHeight += (double)userHeight; } else if (childExpander.IsExpanded) { openExpandersTotalHeight += childExpander.DesiredSize.Height; } else { closedExpandersTotalHeight += childExpander.DesiredSize.Height; } } else if (child as VerticalDragThumb != null) { closedExpandersTotalHeight += child.DesiredSize.Height; } } // Start arranging double usedHeight = 0; double usedWidth = 0; double openSpace = finalSize.Height - closedExpandersTotalHeight; double openHeightDistributionFactor = openSpace / openExpandersTotalHeight; // Multiplication factor for distributing available free space double currentChildHeight = 0; foreach (UIElement child in this.Children) { Expander childExpander = child as Expander; if (childExpander != null) { double?userHeight = (double?)childExpander.GetValue(UserDefinedSizeProperty); // Find height to allocate if (userHeight != null) { currentChildHeight = (double)userHeight; } else if (childExpander.IsExpanded) { currentChildHeight = child.DesiredSize.Height * openHeightDistributionFactor; } else { currentChildHeight = childExpander.DesiredSize.Height; } // Set height property so that its contents wont draw beyond this height childExpander.Height = currentChildHeight - (childExpander.Margin.Top + childExpander.Margin.Bottom + childExpander.Padding.Top + childExpander.Padding.Bottom); childExpander.Arrange( new Rect(0, usedHeight, finalSize.Width, currentChildHeight )); childExpander.SetValue(AllocatedSizeProperty, currentChildHeight); } else if (child as VerticalDragThumb != null) { currentChildHeight = child.DesiredSize.Height; child.Arrange(new Rect(0, usedHeight, finalSize.Width, child.DesiredSize.Height)); } usedHeight += currentChildHeight; usedWidth = child.DesiredSize.Width > usedWidth ? child.DesiredSize.Width : usedWidth; } return(new Size(finalSize.Width, usedHeight)); }