user1151923
user1151923

Reputation: 1872

WrapPanel creates a new column for each dynamically expanding control

I have a vertical WarpPanel that is populated with controls at runtime. The types and number of controls is determined at runtime. It works good with controls that have a fixed height, but controls that expand according to their contents (e.g. Listbox) often create a new column. I somehow need to force the panel to place the controls in the last column as the other, fixed height controls UNLESS the space available in the column is less than MinHeight of the control we are trying to place. Setting Height or MaxHeight for the controls is not an option.

The image below demonstrates the problem. The two listboxes' widths are the same, but instead of putting them in the same column, one of them ends up half-invisible.

Instead of that I would expect to get this:

enter image description here

Is there any way to implement this without making/using a custom panel?

Code:

**Panel:**
<WrapPanel x:Name="wp" Orientation="Vertical">

**Adding controls:**
private void AddControl(bool isListBox)
{
    if (isListBox)
    {
        var lb = new ListBox();
        lb.MinHeight = 310;
        lb.Width = 310;    
        lb.MaxWidth = 310;
        lb.MinWidth = 310;

        wp.Children.Add(lb);
    }
    else
    {
        var cb = new ComboBox();
        cb.Width = 310;
        cb.MaxWidth = 310;

        wp.Children.Add(cb);
    }
}

Upvotes: 2

Views: 252

Answers (1)

Dan Bryant
Dan Bryant

Reputation: 27495

The problem here is that the WrapPanel is always going to give the ListBox as much space as it wants, up to the available height in the WrapPanel. What you want to have happen is something more like a UniformGrid effect, but only for expanding Height elements in the column and only as long as the MinHeight constraint isn't violated. This gets a bit tricky, especially if you have other fixed height elements in-between the ListBox elements or other elements with different MinHeight constraints.

It's possible to do the computation, but I think you'll need to create a custom Panel to get this behavior. Basically, it would work like the WrapPanel code, but when you have variable height elements (elements whose Measure returns unbounded size in the wrap dimension), it needs to look at their MinHeight and accumulate these with the fixed Height elements in the same column, ultimately dividing the remaining non-fixed Height by the number of variable elements, to produce the height(s) that will be provided in the Arrange pass.

Upvotes: 2

Related Questions