-2

Put simply is there any way using one of the inbuilt panels or containers in WPF to have child items stretch to fill width in the ratio of their desired minimum size.

For example if I had a dock panel with last child fill turned off I can get a result like the first image. How can I stretch these elements horizontally to achieve the second image.

Desired layout

Hugoagogo
  • 1,598
  • 16
  • 34
  • 1
    Normally for this you would use a Grid with the "star" sizing: http://stackoverflow.com/questions/1768293/what-does-the-wpf-star-do-width-100. To make it work with minimum size, you would probably have to do some code-behind trickery to get the minimum control size into the grid column width. – vesan Apr 19 '17 at 23:43
  • Sorry I should have specified I have an arbitrary number of items in my collection. – Hugoagogo Apr 20 '17 at 00:42
  • In that case you'll probably need to generate the Grid's ColumnDefinitions dynamically as you add your items. I don't think any other panel will do the resizing the way you need. You can check out [this question](http://stackoverflow.com/questions/9000549/how-can-i-dynamically-add-a-rowdefinition-to-a-grid-in-an-itemspaneltemplate) for some ways to generate rows dynamically (for columns it will be the same thing). – vesan Apr 20 '17 at 05:40

1 Answers1

0

Turns out it is way easier than I thought it was to write a custom panel. For those who are after something like this in an easy to use form.

public class StretchPanel : Panel
{
    protected override Size MeasureOverride(Size availableSize)
    {
        Size size = new Size(0, 0);

        foreach (UIElement child in Children)
        {
            child.Measure(availableSize);
            size.Width += child.DesiredSize.Width;
            size.Height = Math.Max(size.Height, child.DesiredSize.Height);
        }

        size.Width = double.IsInfinity(availableSize.Width) ?
           size.Width : availableSize.Width;

        size.Height = double.IsInfinity(availableSize.Height) ?
           size.Height : availableSize.Height;

        return size;
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
        double total = 0;

        foreach (UIElement child in Children) total += child.DesiredSize.Width;

        double x = 0;

        double factor = Math.Max(finalSize.Width / total,1);

        foreach (UIElement child in Children)
        {
            double adjusted_width = child.DesiredSize.Width * factor;
            child.Arrange(new Rect(x, 0, adjusted_width, finalSize.Height));
            x += adjusted_width;
        }

        return finalSize;
    }
}
Hugoagogo
  • 1,598
  • 16
  • 34