如何使我的网格列始终具有相同的宽度?

11

如果我将列的宽度设置为*,它们一开始是相同的宽度,但如果某个项目大于允许的数量,则会拉伸列宽。

如何强制我的网格保持列的大小,同时明确定义一个大小?

我不能使用UniformGrid,因为这个网格被用在ItemsControl中,并且需要将项目放置在特定的Grid.Row/Grid.Column位置。

编辑 这里是我当前代码的示例。

<DockPanel>

    <!-- Not showing code here for simplicity -->
    <local:ColumnHeaderControl DockPanel.Dock="Top" />
    <local:RowHeaderControl DockPanel.Dock="Left" />

    <ItemsControl ItemsSource="{Binding Events}">
        <ItemsControl.ItemContainerStyle>
            <Style>
                <Setter Property="Grid.Column" 
                        Value="{Binding DueDate.DayOfWeek, 
                            Converter={StaticResource EnumToIntConverter}}" />
            </Style>
        </ItemsControl.ItemContainerStyle>

        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                </Grid>
            </ItemsPanelTemplate>
        </ItemsPanel>
    </ItemsControl>

</DockPanel>

编辑 #2 这是我的最终解决方案。它使列的大小正确,并且在应用程序调整大小时保持大小正确。

<ColumnDefinition Width="{Binding 
    ElementName=RootControl, 
    Path=ActualWidth, 
    Converter={StaticResource MathConverter}, 
    ConverterParameter=(@VALUE-150)/7}" />

150是行标题的宽度加上所有边距和边框。我正在更新我的MathConverter,将其更改为IMultiValueConverter,以便可以绑定两个参数(如果您对转换器代码感兴趣,可以在这里找到,尽管它只是单值转换器)。

5个回答

16

你可以:

1)在DIP中硬编码一个大小:

<ColumnDefinition Width="100" />
<ColumnDefinition Width="100" />
...

2) 使用 SharedSizeGroup,它需要一个 char 参数。

<ColumnDefinition SharedSizeGroup="A" />
<ColumnDefinition SharedSizeGroup="A" />
...

您可以在这里阅读更多相关信息。


1
我不想硬编码宽度,因为网格应该占用所有可用空间,而SharedSizeGroup会使所有项的宽度与最大项相同。 - Rachel
你能贴一些代码吗?这个行为很奇怪。星号大小的列只应在容器调整大小时调整大小,内容不起作用。 - Louis Kottmann
6
对于选项2,您需要将<Grid Grid.IsSharedSizeScope="True">设置为包围网格。 - PeterB

5
你可以尝试将列的宽度绑定到一个属性,该属性将窗口的总宽度除以列数。

我正在尝试解决这个问题,但我遇到的问题是网格不占用全部空间,因此在计算除以7的大小之前,我还必须计算边距、其他控件宽度等。我的基础面板是DockPanel,标题根据需要动态绘制,然后使用ItemsControl来填充所有剩余空间的内容。 - Rachel

4
最简单的方法是使用 UniformGrid,示例如下:
<UniformGrid Rows="1">
    <Rectangle Fill="Blue" />
    <Rectangle Fill="Yellow" />
    <Rectangle Fill="Red" />
</UniformGrid>

当作ItemsPanel使用时,效果更佳。


正如我在问题中所说,我不能使用UniformGrid,因为需要将Items放置在特定的Grid.Row/Grid.Column位置,并且不会填充网格中的每个方格。 - Rachel

1

尝试使用Grid的IsSharedSizeScope功能:

<StackPanel Margin="15" Grid.IsSharedSizeScope="True">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" SharedSizeGroup="A"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="Auto" SharedSizeGroup="B"/>
        </Grid.ColumnDefinitions>

        <TextBlock Grid.Column="0" Text="Col 1"/>
        <TextBox Grid.Column="1" />
        <TextBlock Grid.Column="2" Text="3rd column here"/>
    </Grid>

    <Separator Margin="0,20"/>

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" SharedSizeGroup="A"/>
            <ColumnDefinition />
            <ColumnDefinition SharedSizeGroup="B"/>
        </Grid.ColumnDefinitions>

        <TextBlock Grid.Column="0" Text="1"/>
        <TextBox Grid.Column="1"/>
    </Grid>
</StackPanel>

我希望这能有所帮助。
关于详细描述,请查看此链接: https://wpf.2000things.com/tag/sharedsizegroup/

0

我还没有尝试过,但我认为这应该可以工作:

XAML:

<ColumnDefinition Width="*" Loaded="ColumnDefinition_Loaded"/>

C#:

private void ColumnDefinition_Loaded(object sender, RoutedEventArgs e)
        {
            ((ColumnDefinition)sender).MaxWidth = ((ColumnDefinition)sender).ActualWidth;
        }

问题在于,如果一个项目的宽度超过了“*”所允许的大小,它会将列拉伸到超出该大小。您发布的代码将使所有列等于最大列宽,我不想要那样。 - Rachel
你真的尝试过使用相同的处理程序ColumnDefinition_Loaded来设置所有的列定义吗?代码应该将所有的最大宽度设置为它们所允许的值(*)。在此之后,任何放置在其中的项目都不应改变大小。 - loxxy
是的,我试过了,它使所有列的宽度都与最大项一样宽,这导致网格的部分内容没有显示,因为我没有水平滚动条。此外,标题不再对齐,如果用户调整应用程序的大小,它也不会自动调整大小。 - Rachel
我尝试手动添加项目,所以我猜这就是为什么它没有以那种方式显示给我。抱歉,但我想唯一的解决方案就是像msmucker0527建议的那样手动计算。 - loxxy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接