老实说,当我读到这篇文章时我不相信你,所以我不得不自己去测试它,你确实是对的。不过,我认为您不会有任何运气找到规则,因为进一步的调查使我相信这是 WPF 网格中的错误。我进行了许多测试,看看我是否能弄清楚这种行为,但如果你只是想知道最终结论,请随意翻阅以下谩骂。
抱歉,如果结果不清楚,它们就是我将它们写成作品的方式。前三个数字是我为每列输入的尺寸值,其余的是结果尺寸。
测试1:
<Grid Height="300" Width="300">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="..."/>
<ColumnDefinition Width="..."/>
<ColumnDefinition Width="..."/>
</Grid.ColumnDefinitions>
<Button Grid.ColumnSpan="2" Content="QWERTYUIOP"/>
</Grid>
网格 300 X 300 托管 80 像素宽的控制。网格有三列,控件跨越第 0 列和第 1 列:
30 , auto, * - column 0 - 80, column 1 - 0, column 2 - 220
auto, auto, * - column 0 - 40, column 1 - 40, column 2 - 220
auto, 30 , * - column 0 - 0, column 1 - 80, column 2 - 220
* , 30 , * - column 0 - 135, column 1 - 30, column 2 - 135
* , 30 , 26* - column 0 - 10, column 1 - 30, column 2 - 260
* , auto, * - column 0 - 150, column 1 - 0, column 2 - 150
* , auto, 30* - column 0 - 10, column 1 - 0, column 2 - 290
30 , 30 , * - column 0 - 30, column 1 - 30, column 2 - 240
* , * , 28* - column 0 - 10, column 1 - 10, column 2 - 280
所以从这里我可以想出一些规则:
- 如果一个元素跨越一个自动调整大小的单元格和一个非自动调整大小的单元格,则自动调整大小的单元格将被调整为 0
- 如果一个元素跨越一个固定单元格和一个自动单元格,那么固定单元格的宽度将增加到可以包含整个对象的最小值
- 如果一个元素跨越一个 * 大小的单元格和一个自动大小的单元格,则 * 大小的单元格将具有其预期大小
- 如果一个元素跨越两个自动调整大小的单元格,它们将扩展以适合对象并且宽度相等
- 如果一个元素跨越不包含自动单元格的单元格,则单元格将具有其预期大小
测试 2:
<Grid ShowGridLines="True" Height="300" Width="300">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="..."/>
<ColumnDefinition Width="..."/>
<ColumnDefinition Width="..."/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Grid.ColumnSpan="2" Content="QWERTYUIOP"/>
<Button Grid.Row="1" Grid.Column="1" Content="QWERTYUIOP"/>
</Grid>
网格 300 X 300,3 列托管一个 80 像素宽的控件,跨越第 0 行的第 0 列和第 2 列,第二个控件 80 像素宽,仅位于第 1 行的第 1 列
30 , auto, * - column 0 - 30, column 1 - 80, column 2 - 190
auto, auto, * - column 0 - 0, column 1 - 80, column 2 - 220
auto, 30 , * - column 0 - 0, column 1 - 80, column 2 - 220 (*)
* , 30 , * - column 0 - 135, column 1 - 30, column 2 - 135
* , 30 , 26* - column 0 - 10, column 1 - 30, column 2 - 260
* , auto, * - column 0 - 110, column 1 - 80, column 2 - 110
* , auto, 30* - column 0 - 7, column 1 - 80, column 2 - 213
30 , 30 , * - column 0 - 30, column 1 - 30, column 2 - 240
* , * , 28* - column 0 - 10, column 1 - 10, column 2 - 280
(*) 这并不是真正发生的事情。第 1 列的大小设置为 80,但仅绘制非跨越元素的一部分。我使用按钮作为我的元素,非跨区按钮的镶边填充了 80 像素宽的第一列,但文本被修剪为 30 像素的大小。基本上它完全被搞砸了。
从这个测试中,我可以添加另外两个规则:
- 如果在跨度中使用自动列并且可以从某处获取其大小,它将按预期运行
- 如果在跨度中使用自动列并且无法从其他地方获取它的大小,则测量系统将中断并可能导致图形损坏。
所以,我想我们可以将这些规则组合成一个过度的哲学:
如果一个元素跨越多个列,并且这些列中的至少一个(但不是全部)是自动调整大小的,则必须有另一个不跨越为自动调整大小的列提供大小。否则,该行为充其量是出乎意料的,最坏的情况是破坏性的。
随意向 Microsoft 提出一个错误,但由于现在这是网格控件的定义行为,我想我们在 WPF 的整个生命周期中都会坚持使用它。