WPF 4.0 DataGrid中标题单元格和数据单元格的边框样式不一致。标题单元格的边框包含左侧垂直边框线和标题文本周围的右侧垂直边框线。数据网格文本列数据行的样式使得只有右侧具有垂直边界线。以下示例图像说明了这一点(请注意,网格线颜色已更改为#D0D0D0):
这是放大显示不一致性的相同图像:
如何更改网格标题(可能通过模板或样式)以删除左边框,以便标题垂直边框线与数据边框线对齐?
答案 0 :(得分:19)
要避免这种情况,只需在DataGridColumnHeader样式中添加以下属性设置。
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Margin" Value="-1,-1,0,0" />
此数据网格中的问题是边框绘制发生在左侧的标题单元格边界内。这导致了额外的衬里,如上图所示。如果你还设置了datagrid的broderthickness,那么问题也将出现在单元格的顶部。
希望此设置将解决厚度为“1”时的问题。对于其他厚度,您现在知道需要调整的内容:)
答案 1 :(得分:5)
更新:添加了两个解决方案,两者都会生成
等结果
SeparatorVisibility="Collapsed"
DataGridHeaderBorder
Border
s 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>
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,以便悬停等获得比正常着色更高的ZIndex。为此,我们还需要将DataGridColumnHeader
的ZIndex绑定到DataGridColumnBorder
的ZIndex。
我们可以像这样使用它
<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
答案 2 :(得分:-1)
只需将HeaderStyle中的左边框thichkness设置为0:
<Style x:Key="HeaderStyle" TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="BorderThickness" Value="0,1,1,1"></Setter>
</Style>