Удалите левую границу сетки для столбцов заголовка WPF DataGrid, чтобы соответствовать линиям сетки данных - PullRequest
9 голосов
/ 07 марта 2011

Стили границ для ячеек заголовка и ячеек данных в сетке данных WPF 4.0 несовместимы. Ячейки заголовка имеют границу, которая включает в себя левую вертикальную границу и правую вертикальную границу вокруг текста заголовка.Строки данных текстового столбца сетки данных имеют такой стиль, что только правая сторона имеет вертикальную граничную линию.Следующий пример изображения иллюстрирует это (обратите внимание, что цвет линии сетки был изменен на # D0D0D0):

enter image description here

Это то же изображение, увеличенное для отображения несоответствия:

enter image description here

Как изменить заголовки сетки (возможно, с помощью шаблонов или стилей), чтобы удалить левую границу, чтобы вертикальные границы заголовка совпадали с линиями границы данных?

Ответы [ 3 ]

19 голосов
/ 19 ноября 2012

Чтобы избежать этого, просто добавьте ниже параметр свойства в стиле DataGridColumnHeader.

<Setter Property="BorderThickness" Value="1" />
<Setter Property="Margin" Value="-1,-1,0,0" />

Проблема в этой сетке данных заключается в том, что рисование границы происходит внутри границы ячейки заголовка с левой стороны. Это вызывает дополнительную подкладку, как показано на рисунке выше. Если вы также установите значение расширенной сетки данных, то проблема будет отображаться и для верхней части ячейки.

Надеюсь, что эти настройки решат проблему, когда толщина равна '1'. Для других толщин теперь вы знаете, что вы должны отрегулировать:)

5 голосов
/ 08 марта 2011

Обновление: Добавлено два решения, оба приведут к результату, подобному

enter image description here

Раствор 1

  • Набор SeparatorVisibility="Collapsed" для DataGridHeaderBorder
  • Добавить левый и правый разделитель как Border s
  • Ручка Наведение , Нажатие и Сортировка в триггерах
  • Добавить ссылку на PresentationFramework.Aero

Xaml

<DataGrid ...>
    <DataGrid.ColumnHeaderStyle>
       <Style TargetType="{x:Type DataGridColumnHeader}"
              xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero">
            <Style.Resources>
                <Style x:Key="ColumnHeaderGripperStyle" TargetType="{x:Type Thumb}">
                    <Setter Property="Width" Value="8"/>
                    <Setter Property="Background" Value="Transparent"/>
                    <Setter Property="Cursor" Value="SizeWE"/>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type Thumb}">
                                <Border Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}"/>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
                <LinearGradientBrush x:Key="normalBrush" StartPoint="0,0" EndPoint="0,1">
                    <LinearGradientBrush.GradientStops>
                        <GradientStop Color="#FFF2F2F2" Offset="0" />
                        <GradientStop Color="#FFEFEFEF" Offset="0.4" />
                        <GradientStop Color="#FFE7E8EA" Offset="0.4" />
                        <GradientStop Color="#FFDEDFE1" Offset="1" />
                    </LinearGradientBrush.GradientStops>
                </LinearGradientBrush>
                <LinearGradientBrush x:Key="pressedBrush" StartPoint="0,0" EndPoint="0,1">
                    <LinearGradientBrush.GradientStops>
                        <GradientStop Color="#FF7A9EB1" Offset="0" />
                        <GradientStop Color="#FF7A9EB1" Offset="0.4" />
                        <GradientStop Color="#FF5091AF" Offset="0.4" />
                        <GradientStop Color="#FF4D8DAD" Offset="1" />
                    </LinearGradientBrush.GradientStops>
                </LinearGradientBrush>
                <LinearGradientBrush x:Key="hoveredBrush" StartPoint="0,0" EndPoint="0,1">
                    <LinearGradientBrush.GradientStops>
                        <GradientStop Color="#FF88CBEB" Offset="0" />
                        <GradientStop Color="#FF88CBEB" Offset="0.4" />
                        <GradientStop Color="#FF69BBE3" Offset="0.4" />
                        <GradientStop Color="#FF69BBE3" Offset="1" />
                    </LinearGradientBrush.GradientStops>
                </LinearGradientBrush>
                <SolidColorBrush x:Key="sortedBrush" Color="#FF96D9F9"/>
            </Style.Resources>
            <Setter Property="VerticalContentAlignment" Value="Center"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="Auto"/>
                            </Grid.ColumnDefinitions>
                            <Border x:Name="separatorLeft" Grid.Column="0" Width="1" HorizontalAlignment="Left"
                                    Background="{StaticResource normalBrush}">
                                <Border.RenderTransform>
                                    <TranslateTransform X="-1"/>
                                </Border.RenderTransform>
                            </Border>
                            <Microsoft_Windows_Themes:DataGridHeaderBorder x:Name="headerBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" IsClickable="{TemplateBinding CanUserSort}" IsPressed="{TemplateBinding IsPressed}" IsHovered="{TemplateBinding IsMouseOver}" Padding="{TemplateBinding Padding}" SortDirection="{TemplateBinding SortDirection}" SeparatorBrush="{TemplateBinding SeparatorBrush}"
                                                                            SeparatorVisibility="Collapsed">
                                <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                            </Microsoft_Windows_Themes:DataGridHeaderBorder>
                            <Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left" Style="{StaticResource ColumnHeaderGripperStyle}"/>
                            <Thumb x:Name="PART_RightHeaderGripper" HorizontalAlignment="Right" Style="{StaticResource ColumnHeaderGripperStyle}"/>
                            <Border x:Name="separatorRight" Grid.Column="1" Width="1" Background="{StaticResource normalBrush}"/>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsPressed" Value="True">
                                <Setter TargetName="separatorRight" Property="Background" Value="{StaticResource pressedBrush}"/>
                                <Setter TargetName="separatorLeft" Property="Background" Value="{StaticResource pressedBrush}"/>
                                <Setter Property="Panel.ZIndex" Value="2"/>
                            </Trigger>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter TargetName="separatorRight" Property="Background" Value="{StaticResource hoveredBrush}"/>
                                <Setter TargetName="separatorLeft" Property="Background" Value="{StaticResource hoveredBrush}"/>
                                <Setter Property="Panel.ZIndex" Value="2"/>
                            </Trigger>
                            <Trigger Property="SortDirection" Value="Ascending">
                                <Setter TargetName="separatorRight" Property="Background" Value="{StaticResource sortedBrush}"/>
                                <Setter TargetName="separatorLeft" Property="Background" Value="{StaticResource sortedBrush}"/>
                                <Setter Property="Panel.ZIndex" Value="2"/>
                            </Trigger>
                            <Trigger Property="SortDirection" Value="Descending">
                                <Setter TargetName="separatorRight" Property="Background" Value="{StaticResource sortedBrush}"/>
                                <Setter TargetName="separatorLeft" Property="Background" Value="{StaticResource sortedBrush}"/>
                                <Setter Property="Panel.ZIndex" Value="2"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </DataGrid.ColumnHeaderStyle>
    <!--...-->
</DataGrid>

Раствор 2

Разделители для DataGridColumnHeader отображаются в методе RenderTheme в DataGridHeaderBorder. Этот класс в значительной степени является соглашением «все или ничего», так как изменение любого свойства в нем отключит весь стиль (без рамки, без стрелок сортировки и т. Д.). Это также запечатано, поэтому мы не можем извлечь из него. Однако мы можем скопировать весь класс и заставить DataGridColumnHeader использовать этот класс.

Часть, которая рисует разделители, выглядит следующим образом

private void RenderTheme(DrawingContext dc)
{
    // ...
            if (this.SeparatorVisibility == Visibility.Visible)
            {
                // ...
                // Draw Left Separator
                dc.DrawRectangle(separatorBrush, null, new Rect(0, 0.0, 1.0, Max0(renderSize.Height - 0.95)));
                // Draw Right Separator
                dc.DrawRectangle(separatorBrush, null, new Rect(renderSize.Width - 1.0, 0.0, 1.0, Max0(renderSize.Height - 0.95)));
            }

Отсюда мы могли бы просто удалить левый разделитель и получить ширину разделителя 1 вместо 2, но тогда мы получим неправильную раскраску для левой стороны, когда Наведение , Нажатие или Сортировка столбца. Чтобы преодолеть это, мы можем переместить левый разделитель на 1 влево и изменить ZIndex, чтобы Hovering и т. Д. Получал более высокий ZIndex, чем обычная окраска. Чтобы это работало, нам также необходимо привязать ZIndex DataGridColumnHeader к ZIndex DataGridColumnBorder.

Мы можем использовать это так

<DataGrid ...>
    <DataGrid.ColumnHeaderStyle>
        <Style TargetType="{x:Type DataGridColumnHeader}">
            <Style.Resources>
                <Style x:Key="ColumnHeaderGripperStyle" TargetType="{x:Type Thumb}">
                    <Setter Property="Width" Value="8"/>
                    <Setter Property="Background" Value="Transparent"/>
                    <Setter Property="Cursor" Value="SizeWE"/>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type Thumb}">
                                <Border Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}"/>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </Style.Resources>
            <Setter Property="VerticalContentAlignment" Value="Center"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
                        <Grid>
                            <local:MyDataGridHeaderBorder Panel.ZIndex="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGridColumnHeader}}, Path=(Panel.ZIndex), Mode=TwoWay}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" IsClickable="{TemplateBinding CanUserSort}" IsPressed="{TemplateBinding IsPressed}" IsHovered="{TemplateBinding IsMouseOver}" Padding="{TemplateBinding Padding}" SortDirection="{TemplateBinding SortDirection}" SeparatorBrush="{TemplateBinding SeparatorBrush}" SeparatorVisibility="{TemplateBinding SeparatorVisibility}">
                                <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                            </local:MyDataGridHeaderBorder>
                            <Thumb x:Name="PART_LeftHeaderGripper" Panel.ZIndex="4" HorizontalAlignment="Left" Style="{StaticResource ColumnHeaderGripperStyle}"/>
                            <Thumb x:Name="PART_RightHeaderGripper" Panel.ZIndex="4" HorizontalAlignment="Right" Style="{StaticResource ColumnHeaderGripperStyle}"/>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </DataGrid.ColumnHeaderStyle>
    <!--...-->
</DataGrid>

MyDataGridHeaderBorder было слишком большим для публикации, поэтому я загрузил его здесь: MyDataGridHeaderBorder.cs

0 голосов
/ 12 июня 2014

Просто установите thichkness левой границы в HeaderStyle на 0:

<Style x:Key="HeaderStyle" TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="BorderThickness" Value="0,1,1,1"></Setter>
</Style>
...