Grid inside a StackPanel: why do auto and * behave strangely?

pfw picture pfw · Nov 18, 2011 · Viewed 8.4k times · Source

My google and stackoverflow search-fu have failed me, so I present to the community this question.

(This is all generated using VS2010 and .NET 4.0, in a blank default WPF Solution)

Consider the following XAML:

<StackPanel Orientation="Horizontal">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="20"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <Border Name="aborder" Grid.Column="0" Grid.ColumnSpan="2" 
                    Background="Red" Width="200"/>
        <Border Name="aborder2" Background="Green"/>

    </Grid>
</StackPanel>

What would you predict the width of "aborder2" to be?

If you guessed "20 pixels", you would be wrong. The correct answer is 110 pixels.

Consider this XAML:

    <StackPanel Orientation="Horizontal">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="20"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>

        <Border Name="aborder" Grid.Column="0" Grid.ColumnSpan="2" 
                    Background="Red" Width="200"/>
        <Border Name="aborder2" Background="Green"/>

    </Grid>
</StackPanel>

What would you predict the width of "aborder2" to be?

If you guessed either 20 pixels or 110 pixels, you would be wrong. The correct answer is 200 pixels.

I cannot figure this out and it's driving me insane. It seems like the answer should be obvious; clearly there's some interaction between an auto-filling grid column and the stackpanel that causes the grid to freak out. But it just doesn't seem to make sense - whatever rules are governing this behavior seem to be arbitrary. Why 110 pixels? Why not 109 pixels or 100 pixels? I would understand if the auto-sized column failed to expand fully or something, but to have the fixed-width column randomly ignore its width has left me a burnt out shell of a developer.

Any help or guiding lights would be much appreciated!

Answer

Rachel picture Rachel · Nov 18, 2011

I have no idea why the first example isn't rendering correctly

The 2nd is because Auto means "the same size as the contents", but you have nothing in Column2 so Column2 is getting rendered at 0px. You have something in Column1 which spans 2 cells, but since Column2 is rendered at 0 px it means Column1 is stretched to 200 px. By default, Grid's expand their children to fill all available space in the Cell, so this is making aborder2 stretch to 200px instead of 20.

I think the first example might be a similar situation, where Column2 is rendering at 0px because it has no content, however I am not sure why it is setting aborder2 to a width of 110. The 110 seems to come from (GridWidth / TotalColumns) + (1stColumnWidth / TotalColumns * NumberOfStarColumns), so I think it's a bug.

As a side note, you can set a Column1's MaxWidth="20" to force Column1 to always render as 20px