Setting a WPF control to expand to fill available space, and no more
autosize, height, scroll, stretching, wpf
Solution
To solve the same problem I wrote special container class:
class FrugalContainer : Decorator
{
protected override Size MeasureOverride(Size availableSize)
{
return new Size(0, 0);
}
protected override Size ArrangeOverride(Size arrangeSize)
{
// get it all
Child.Measure(arrangeSize);
Child.Arrange(new Rect(arrangeSize));
return Child.RenderSize;
}
}
Surround your ListBox by the container and the height of ListBox will be the same as of Expander.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<FrugalContainer Grid.Row="0" Grid.Column="0" >
<ListBox />
</FrugalContainer>
<Expander Grid.Row="0" Grid.Column="1" Header="Expander" />
</Grid>
Note that I remove `Width="Auto"` from column's definition because the FrugalContainer will be as small as it can. So you can't set the width or height of the parent grid's cell to Auto.
If you need autosizing, rewrite the container:
class FrugalHeightContainer : Decorator
{
protected override Size MeasureOverride(Size availableSize)
{
Child.Measure(availableSize);
return new Size(Child.DesiredSize.Width, 0);
}
protected override Size ArrangeOverride(Size arrangeSize)
{
Child.Measure(arrangeSize);
Child.Arrange(new Rect(arrangeSize));
return Child.RenderSize;
}
}
Problem
How can I set up a WPF control to fill the available space in its parent's container, but not expand the parent? The following snippet describes the layout I am attempting. I would like the `Grid` to stretch to accommodate the `Expander`, and I would like the `ListBox` only to fill the `Grid`. I want the `ListBox`'s scroll bar to appear when the `Grid` is too small to show all the `ListBoxItem`s. ``` <ScrollViewer> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition /> </Grid.RowDefinitions> <ListBox Grid.Row="0" Grid.Column="0" /> <Expander Grid.Row="0" Grid.Column="1" Header="Expander" /> </Grid> </ScrollViewer> ``` Currently what happens is that the `Grid` stretches to fit the entire `ListBox`, and the outer `ScrollViewer`'s vertical scroll bar appears. I only want the outer scroll bar to appear when the `Expander` gets too big to fit on screen.