正在查找WPF网格列跨度行为的解释

正在查找WPF网格列跨度行为的解释,wpf,xaml,grid,columnspan,Wpf,Xaml,Grid,Columnspan,我问了一个问题,但仍然缺乏一个奇怪的行为很好的解释 运行以下XAML显示,即使列设置为宽度100,列0中的TextBlock的宽度也大于100。我认为这种奇怪可能与它被包装在ScrollViewer中有关,但我不知道为什么。如果在列上设置MaxWidth,效果很好,但设置Width则不行 为什么不遵守第0列的宽度 为什么移除滚动查看器时,列大小的行为会有所不同 谢谢你的解释!这对我来说真是个谜 <Window x:Class="WpfApplication2.MainWindow" xml

我问了一个问题,但仍然缺乏一个奇怪的行为很好的解释

运行以下XAML显示,即使列设置为宽度100,列0中的TextBlock的宽度也大于100。我认为这种奇怪可能与它被包装在ScrollViewer中有关,但我不知道为什么。如果在列上设置MaxWidth,效果很好,但设置Width则不行

  • 为什么不遵守第0列的宽度
  • 为什么移除滚动查看器时,列大小的行为会有所不同
  • 谢谢你的解释!这对我来说真是个谜

    <Window x:Class="WpfApplication2.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Width="300">
        <ScrollViewer HorizontalScrollBarVisibility="Auto" >
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="100" />
                    <ColumnDefinition Width="100" />
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
                <TextBlock x:Name="textBlock" Text="{Binding ElementName=textBlock, Path=ActualWidth}" />
                <TextBlock Text="column 1" Grid.Column="1" />
                <TextBlock Grid.Row="1" Grid.ColumnSpan="3" Text="text here that is wider than the first two columns combined" />
            </Grid>
        </ScrollViewer>
    </Window>
    

    这是一个非常好的问题,它测试了我们直觉的局限性。它揭示了网格布局逻辑的实现细节

    不接受宽度为100,因为:

  • 第三列中没有任何内容会导致栅格为其指定宽度
  • 第二行的长文本比前两列的宽
  • 当栅格的宽度不受其父栅格的约束或设置时,其布局逻辑显然会拉伸第一列而不是最后一列 通过在第一列上放置MaxWidth,可以约束网格的布局逻辑,因此它将移动到第二列并拉伸它。你会注意到,在这种情况下,它的宽度将超过100

    但是,一旦网格的宽度设置为特定值或受其父项约束(例如,当窗口中没有ScrollViewer时),网格的宽度就具有特定值,并且第三列即使为空也会获得设置的宽度。现在网格的自动大小代码被禁用,它不再拉伸任何列以尝试压缩该文本。您可以通过在网格上放置特定的宽度来看到这一点,即使它仍然在ScrollViewer中


    编辑:现在我在您的原始线程中阅读了MSDN支持的答案,我相信它是正确的,这意味着这可能是附加属性实现的结果,而不是网格本身。但是,原则是一样的,希望我的解释足够清楚,能够理解这里的微妙之处。

    简短回答:
    其原因是:
    1.存在ScrollViewer,允许网格(如果愿意)采用任何所需大小。
    2.网格没有明确的宽度。
    3.未指定宽度的列(第2列),将其设置为1*,使其最终大小取决于网格和其他列的大小。
    4.TextBlock,其colspan超过三列

    如果你:
    1.移除scrollviewer,网格只允许增长到窗口的客户端区域(在您的示例中约为278),长文本块必须适应此宽度,否则将被修剪。
    2.设置网格的显式宽度,这将再次修剪textblock以使其适合。
    3.设置第2列的显式宽度,该列为栅格提供固定宽度(100+100+宽度\u of_col2),这将再次修剪textblock以适应。
    4.删除colspan,不包含colspan且定义了固定宽度的列将采用该宽度

    发生的事情如下:
    这是一个粗糙而不精确的解释,然而,它应该给出一个公平的想法。

    从col0开始,100表示满意,col1表示满意,col2表示满意。基于此,网格的大小将为100+100+0=200。当Grid请求对其子项(textblocks)进行测量时,它会发现前两个textblocks适合其列的宽度。然而,第三个文本块需要288个。由于grid在scrollviewer中没有定义任何宽度和宽度,所以如果它的一个子项需要,它可以增加其大小。网格现在必须将其大小从200增加到288(即增加88)。这意味着textblock跨越的每一列(全部三列)将扩展88/3~=29像素。这使得col0=100+29=129,col1=100+29=129,col2=0+29。

    试试这个:
    包括一个矩形,将其放在col2中,并将矩形的宽度设置为20。

    这就是正在发生的事情:
    首先,col0和col1各有100个文本块,因为它们各自需要的文本块少于100个。col2对20表示满意,因为它需要20。基于此网格的宽度为100+100+20=220。但是,由于文本块的列跨度,网格的大小必须从220增加到288(即增加68)。这意味着textblock跨越的每一列(全部三列)将扩展68/3~=23像素。这使得col0=100+23=123,col1=100+23=123,col2=20+23=43


    HTH.

    这里是另一个示例,它显示了使用
    画布而不是
    滚动查看器出现的问题:

    <Canvas>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="100"/>
                <ColumnDefinition Width="100"/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column="0" x:Name="textBlock1" Text="{Binding ElementName=textBlock1, Path=ActualWidth}"/>
            <TextBlock Grid.Column="1" x:Name="textBlock2" Text="{Binding ElementName=textBlock2, Path=ActualWidth}"/>
            <TextBlock Grid.Row="1" Grid.ColumnSpan="3" Width="300"/>
        </Grid>
    </Canvas>
    
    这种方法通过防止大小约束具有正无穷大的概率值来避免错误,同时实际上实现了相同的效果

    但这是:

    <Grid MaxWidth="{x:Static sys:Double.PositiveInfinity}">
    
    
    

    将触发错误。

    我将此问题报告为错误:


    如果您同意这是一个bug,请在该链接上投票。

    谢谢您深思熟虑的回答。正如我在评论这篇文章前面的答案时所说的,这让我想知道:1。为什么MaxWidth比固定宽度更受尊重?2.您认为这是网格控件中的缺陷还是网格控件在MSDN上的文档中的缺陷?我在MSDN中没有看到任何接近于描述这种行为的内容。我很想将此记录为缺陷。这不是“尊重”MaxWidth而不是Width的问题。一个是约束,另一个是初始起始值。如果存在bug,则是ColSpan attached属性影响布局的天真方式。第三柱
    <Grid MaxWidth="{x:Static sys:Double.PositiveInfinity}">