堆叠面板中的网格:为什么自动和*的行为会很奇怪?

时间:2021-08-07 20:05:07

My google and * 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)

(所有这些都是使用VS2010和。net 4.0在一个空白的默认WPF解决方案中生成的)

Consider the following XAML:

考虑下面的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?

“aborder2”的宽度是多少?

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

如果你猜“20像素”,你就错了。正确的答案是110像素。

Consider this XAML:

考虑一下这个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?

“aborder2”的宽度是多少?

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

如果你猜20或110像素,你就错了。正确的答案是200像素。

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.

我搞不清楚,简直要把我逼疯了。答案似乎显而易见;显然,在自动填充网格列和导致网格崩溃的stackpanel之间存在一些交互。但这似乎没有任何意义——任何控制这种行为的规则似乎都是随意的。110像素的原因吗?为什么不是109或100像素呢?如果自动大小的列不能完全展开,我可以理解,但是如果让固定宽度的列随机忽略它的宽度,会给我留下一个开发人员精疲力竭的外壳。

Any help or guiding lights would be much appreciated!

任何帮助或指路灯将非常感谢!

2 个解决方案

#1


3  

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.

第二是因为Auto的意思是“和内容一样大”,但是你在n2中什么都没有,所以Column2在0px被渲染。在Column1中有一个东西,它跨越两个单元,但是由于Column2在0 px上呈现,这意味着Column1被扩展到200 px。默认情况下,Grid将子元素展开以填充单元格中的所有可用空间,因此这会使aborder2扩展到200px而不是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.

我认为第一个例子可能是类似的情况,Column2在0px上呈现,因为它没有内容,但是我不确定为什么它将aborder2设置为110。110似乎来自(GridWidth / TotalColumns) + (1stColumnWidth / TotalColumns * NumberOfStarColumns),所以我认为这是一个bug。

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

作为补充说明,您可以设置Column1的MaxWidth=“20”,以强制Column1总是呈现为20px

#2


1  

No answer for you, but it seems to happen in Silverlight too. I'd assume there's some bug in the arrange and measure passes. If you put a custom control in there instead of a border and override the measure and arrange methods you would probably get a better picture of what's going on.

你没有答案,但它似乎也发生在银光。我假设在安排和测量通过中有一些错误。如果你在那里放置一个自定义控件而不是边框,覆盖度量和排列方法,你可能会对正在发生的事情有一个更好的了解。

To try to solve the mystery of where 110 comes from, I'm guessing (200 - 20) / 2 + 20

我猜(200 - 20)/ 2 + 20,试图解开110的奥秘。

EDIT: I tried a few other formulas and it didn't hold up, looks more like:

编辑:我尝试了其他一些公式,但没有成功,看起来更像:

(200 + 20) / 2

(200 + 20) / 2

#1


3  

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.

第二是因为Auto的意思是“和内容一样大”,但是你在n2中什么都没有,所以Column2在0px被渲染。在Column1中有一个东西,它跨越两个单元,但是由于Column2在0 px上呈现,这意味着Column1被扩展到200 px。默认情况下,Grid将子元素展开以填充单元格中的所有可用空间,因此这会使aborder2扩展到200px而不是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.

我认为第一个例子可能是类似的情况,Column2在0px上呈现,因为它没有内容,但是我不确定为什么它将aborder2设置为110。110似乎来自(GridWidth / TotalColumns) + (1stColumnWidth / TotalColumns * NumberOfStarColumns),所以我认为这是一个bug。

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

作为补充说明,您可以设置Column1的MaxWidth=“20”,以强制Column1总是呈现为20px

#2


1  

No answer for you, but it seems to happen in Silverlight too. I'd assume there's some bug in the arrange and measure passes. If you put a custom control in there instead of a border and override the measure and arrange methods you would probably get a better picture of what's going on.

你没有答案,但它似乎也发生在银光。我假设在安排和测量通过中有一些错误。如果你在那里放置一个自定义控件而不是边框,覆盖度量和排列方法,你可能会对正在发生的事情有一个更好的了解。

To try to solve the mystery of where 110 comes from, I'm guessing (200 - 20) / 2 + 20

我猜(200 - 20)/ 2 + 20,试图解开110的奥秘。

EDIT: I tried a few other formulas and it didn't hold up, looks more like:

编辑:我尝试了其他一些公式,但没有成功,看起来更像:

(200 + 20) / 2

(200 + 20) / 2