Limit stack width to smallest child

How can I constrain WPF vertical width StackPanel

to the narrowest element it contains. The width StackPanel

must not be greater than the width of any other child.

0


source to share


3 answers


Unfortunately, the IValueConverter approach won't always work; if children are added to the StackPanel statically, for example, the child collection will be empty at the time of binding (which is why I found out). The simplest solution is to create a custom panel:

public class ConstrainedStackPanel : StackPanel
{
    public ConstrainedStackPanel()
    {
    }

    protected override Size MeasureOverride(Size constraint)
    {
        foreach (var item in this.Children)
        {
            // FrameworkElement has the Width property we care about.
            FrameworkElement element = item as FrameworkElement;
            if (element != null)
                constraint.Width = Math.Min(element.Width, constraint.Width);
        }

        return base.MeasureOverride(constraint);
    }

    protected override Size ArrangeOverride(Size arrangeSize)
    {
        foreach (var item in this.Children)
        {
            // FrameworkElement has the Width property we care about.
            FrameworkElement element = item as FrameworkElement;
            if (element != null)
                arrangeSize.Width = Math.Min(element.Width, arrangeSize.Width);
        }

        return base.ArrangeOverride(arrangeSize);
    }
}

      

You can use the panel as shown in the following XAML:

<StackPanel Margin="5">
    <TextBlock Text="StackPanel:" FontWeight="Bold" />
    <StackPanel x:Name="panelA">
        <Button Width="100" Content="100" />
        <Button Width="200" Content="200" />
        <Button Width="300" Content="300" />
        <Button Width="400" Content="400" />
    </StackPanel>
    <TextBlock Text="ConstrainedStackPanel:" FontWeight="Bold" Margin="0,10,0,0" />
    <l:ConstrainedStackPanel x:Name="panelB">
        <Button Width="100" Content="100" />
        <Button Width="200" Content="200" />
        <Button Width="300" Content="300" />
        <Button Width="400" Content="400" />
    </l:ConstrainedStackPanel>
</StackPanel>

      



Which will look something like this:

ScreenShot

Hope this helps.

+2


source


You can not. A vertically oriented StackPanel

one will always allocate as much width as the request of its children.



Your best bet is to write a custom panel to achieve the desired behavior.

+1


source


I tried to bind the ActualWidth property, even creating a converter to offset the value, and that works fine with one exception: when the container size expands, the width is updated as expected, but when the container needs to be made smaller, the actual content width gets smaller, but the "page width" of any scroll will not be. I'm sure there is a way around this, but I haven't found one.

+1


source







All Articles