在使用自定义列头样式时,WPF DataGrid的列会错位一个像素

编程语言 2026-07-08

我有一个包含五列的DataGrid。当我在这个DataGrid上应用一个特定的ColumnHeaderStyle时,某些列似乎向右错位了一个像素。分隔这些列的垂直线似乎有时宽出一个像素、有时窄出一个像素,我在尝试弄清楚造成这种现象的原因。

这就是DataGrid。我当前隐藏了最右边的列,效果在“Example 3”和“Example 4”列之间清晰可见。

<DataGrid Grid.Row="4"
          ItemsSource="{Binding ConditionTypeParameters}"
          IsReadOnly="True"
          AutoGenerateColumns="False"
          Margin="0,20,0,10"
          ColumnHeaderStyle="{StaticResource TableHeader}"
          CanUserResizeColumns="False"
          CanUserResizeRows="False"
          CanUserSortColumns="False"
          RowHeaderWidth="0"
          MinRowHeight="40"
          SelectionMode="Single"
          SelectionUnit="Cell"
          SelectedIndex="{Binding SelectedIndex, Mode=TwoWay}">
    <DataGrid.Columns>
        <DataGridTextColumn Width="Auto"
                            Foreground="White"
                            CanUserReorder="False"
                            CanUserSort="False">
            <DataGridTextColumn.HeaderTemplate>
                <DataTemplate>
                    <TextBlock Text="Example 1" />
                </DataTemplate>
            </DataGridTextColumn.HeaderTemplate>
        </DataGridTextColumn>
        <DataGridTextColumn Width="*"
                            CanUserReorder="False"
                            CanUserSort="False">
            <DataGridTextColumn.HeaderTemplate>
                <DataTemplate>
                    <TextBlock Text="Example 2" />
                </DataTemplate>
            </DataGridTextColumn.HeaderTemplate>

        </DataGridTextColumn>
        <DataGridTextColumn Width="*"
                            CanUserReorder="False"
                            CanUserSort="False">
            <DataGridTextColumn.HeaderTemplate>
                <DataTemplate>
                    <TextBlock Text="Example 3" />
                </DataTemplate>
            </DataGridTextColumn.HeaderTemplate>
        </DataGridTextColumn>
        <DataGridTextColumn Width="*"
                            Visibility="{x:Static Visibility.Visible}"
                            CanUserReorder="False"
                            CanUserSort="False">
            <DataGridTextColumn.HeaderTemplate>
                <DataTemplate>
                    <TextBlock Text="Example 4" />
                </DataTemplate>
            </DataGridTextColumn.HeaderTemplate>
        </DataGridTextColumn>
        <DataGridTextColumn Width="*"
                            Visibility="{x:Static Visibility.Collapsed}"
                            CanUserReorder="False"
                            CanUserSort="False">
            <DataGridTextColumn.HeaderTemplate>
                <DataTemplate>
                    <TextBlock Text="Example 5" />
                </DataTemplate>
            </DataGridTextColumn.HeaderTemplate>
        </DataGridTextColumn>
    </DataGrid.Columns>
</DataGrid>

第三列和第四列之间有一条白线分隔,第四列中被选中的单元格让这个问题更加明显。 在此处输入图片描述

ColumnHeaderStyleDataGrid中移除后,问题似乎就消失了。以下是应用的样式:

<Style x:Key="TableHeader"
       TargetType="{x:Type DataGridColumnHeader}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
                <Border x:Name="BackgroundBorder"
                        BorderThickness="1"
                        BorderBrush="#DBDBDB"
                        Padding="2"
                        Background="Red">
                    <ContentPresenter VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                      HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                      SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

应用该样式时,即使第四列可见也会出现这个问题。在这种情况下,第三列和第四列表头之间的分界线明显更细。被选中的单元格的左边边框也更细。

第三列和第四列之间的分隔变得更薄,这种效果在所选单元格上也能看到。 在此处输入图片描述

BorderThickness设为0并去除样式中的填充并不能解决问题: 在此处输入图片描述

没有边框时,白线会更加明显。把MarginPadding都设为0,得到的结果也是一样的。

在寻求解决方案的过程中,我看到一篇描述看起来类似问题的帖子。列之间会出现一条白色竖线,但很遗憾,帖子中的推荐方案并不适用于我的情况,因为我需要对同一行上的单元格应用不同的背景色(上面的最小示例中没有展示)。此外,我也不认为该推荐方案解决了问题的根本原因:

调整DataGrid大小时出现意外垂直线

是我的样式引起这个问题吗?造成这种行为的原因是什么?

解决方案

Gerry Schmitz的评论把我引向了正确的方向:问题其实是对齐问题。

父级布局Grid包含一个隐式宽度为*的列,由于项目需要,窗口大小是固定的。根据可用宽度,分配给DataGrid的空间可能引入一个像素的偏移。这导致某些列分隔符看起来比其他的更薄或更厚。

ColumnHeaderStyle让问题更加明显,但它并非根本原因。

新增一个宽度设为Auto的新父级Grid即可消除那条不希望出现的白线: 没有对齐问题时的结果

在我的情况下,这些单元格大多保持为空,因此我在用Width="*"定义的DataGridTextColumn上设置了MinWidth,以便让DataGrid在需要时能扩展。

以下是最终的布局:

<Grid Grid.Row="4"
      HorizontalAlignment="Center">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>
    <DataGrid Grid.Column="0"
              ItemsSource="{Binding ConditionTypeParameters}"
              IsReadOnly="True"
              AutoGenerateColumns="False"
              Margin="0,20,0,10"
              ColumnHeaderStyle="{StaticResource TableHeader}"
              CanUserResizeColumns="False"
              CanUserResizeRows="False"
              CanUserSortColumns="False"
              RowHeaderWidth="0"
              MinRowHeight="40"
              SelectionMode="Single"
              SelectionUnit="Cell"
              SelectedIndex="{Binding SelectedIndex, Mode=TwoWay}">
        <DataGrid.Columns>
            <DataGridTextColumn Width="Auto"
                                Foreground="White"
                                CanUserReorder="False"
                                CanUserSort="False">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock Text="Example 1" />
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
            </DataGridTextColumn>
            <DataGridTextColumn Width="*"
                                MinWidth="150"
                                CanUserReorder="False"
                                CanUserSort="False">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock Text="Example 2" />
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
            </DataGridTextColumn>
            <DataGridTextColumn Width="*"
                                MinWidth="150"
                                CanUserReorder="False"
                                CanUserSort="False">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock Text="Example 3" />
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
            </DataGridTextColumn>
            <DataGridTextColumn Width="*"
                                MinWidth="150"
                                Visibility="{x:Static Visibility.Visible}"
                                CanUserReorder="False"
                                CanUserSort="False">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock Text="Example 4" />
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
            </DataGridTextColumn>
            <DataGridTextColumn Width="*"
                                MinWidth="150"
                                Visibility="{x:Static Visibility.Visible}"
                                CanUserReorder="False"
                                CanUserSort="False">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock Text="Example 5" />
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
            </DataGridTextColumn>
        </DataGrid.Columns>
    </DataGrid>
</Grid>
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章