views:

5301

answers:

3

I have a vertical StackPanel with two elements: a Button and a ListBox. How can I have the ListBox stretch to the remaining page height?

<StackPanel Height="Auto" Width="Auto">
    <Button Height="30" Width="100" Content="Get Content" x:Name="GetContent"/>
    <ListBox Height="Auto" Width="Auto" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
</StackPanel>

Note that I got this to work using a Grid container:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Button Width="100" Height="30" Content="Get Content" Click="OnGetContent" Grid.Row="0" Grid.Column="0"/>
    <data:DataGrid x:Name="MyContent" Margin="0,5" Grid.Row="1" Grid.Column="0"/>
</Grid>
+4  A: 

You can use a DockPanel. Set the first item to dock top and the second to dock fill, or use the LastChildFill property:

<DockPanel LastChildFill="True">    
    <Button DockPanel.Dock="Top" Height="30" Width="100" 
     Content="Get Content" x:Name="GetContent"/>
    <ListBox Background="Azure" />
</DockPanel>
Mark Heath
Thanks for the answer. A slight 'problem' is that the DockPanel isn't available (yet?) by default and that you need the Silverlight Toolkit. I find it strange though that although the Grid does provide a Height="*" (take remaining space / add stretched) functionality a simple StackPanel doesn't.
crimson13
I found the DockPanel the best solution here as I had 2 datagrids inside a Scrollviewer and this is the only thing that worked.
Rodney
+9  A: 

Well, you already found the solution ;) StackPanels won't fill any remaining space by default because their size is always equal to the combined required size of their child elements. Grid is a great way to go because it will dynamically resize when the browser size changes. Mark's answer of using a DockPanel works fine too. The only other method would be to manually size the elements when the parent control's size changes. In general through, stick with Grids for the outer layout and they fill them up with StackPanels and other controls and you should be set.

James Cadd
+2  A: 

I agree with James' observation that "StackPanels won't fill any remaining space by default because their size is always equal to the combined required size of their child elements." That is exactly what happens, but this isn't the expected result.

I can see why this instruction would compress the contents into the smallest necessary space.

<StackPanel Height="Auto" Width="Auto">

However... StackPanel accepts a HorizontalAlignment argument - which if selected should cause the stack panel to fill the contents of its parent container. This is exactly what happens when you set Orientation="Vertical". Observe that in this case the StackPanel will determine how much horizontal space is available and allocated it to the child controls.

<StackPanel Height="30" Orientation="Vertical" HorizontalAlignment="Stretch" > 
   <TextBox /> <!--TextBox fills entire space-->
</StackPanel>

Its only when Orientation="Horizontal" that the Horizontal child sizing breaks down.

<StackPanel Height="30" Orientation="Horizontal" HorizontalAlignment="Stretch" > 
   <TextBox /> <!--TextBox fills smallest space available-->
</StackPanel>
Slug
I'm also struggling with this at the moment (I'm using WPF though). Setting Orientation="Horizontal" on StackPanel somehow prevents it from stretching with HorizontalAlignment="Stretch".
aks
I just ran into this... it seems like a bug more than anything.
Porges