感谢@Aran 的回答以及我在 Codeplex 讨论中找到的几篇文章(请参阅http://wpf.codeplex.com/Thread/View.aspx?ThreadId=65069),我设法想出了一组样式允许在不放弃功能(排序箭头、分隔符等)的情况下设置标题行的背景。
一个例外是“单元格选择”功能。DataGrid 有一个SelectionUnit
属性,可以设置为 Cell、FullRow 或 CellOrRowHeader,但似乎不起作用。如果我将其设置为(无论您在何处单击该行,它FullRow
都应该只选择整行),当您单击它们时,它仍然会在视觉上选择单个单元格。下图显示了一个 DataGrid 示例(未应用样式),其中SelectionUnit="FullRow"
. 如您所见,看起来确实有一个单元格被选中(名称列的 G 行)。因为我目前不需要单元格选择,所以我设计了我的样式来抑制单击单元格时出现在单元格周围的深黑色边框。
替代文字 http://img80.imageshack.us/img80/4757/datagriddefaultcellsele.jpg
下面是一个按 ID 降序排序的样式化 DataGrid 示例。如您所见,向下箭头出现在 ID 标签旁边,并且该列已适当地自动调整大小以为排序箭头腾出空间。
替代文字 http://img377.imageshack.us/img377/3836/datagridcustomfixed.jpg
这是样式化 DataGrid 的另一个示例。这个按“保存?”升序排序。请注意,标题居中,但它仍然在两侧为排序箭头留出足够的空间。
替代文字 http://img203.imageshack.us/img203/5140/datagridcustomfixed2.jpg
以下是实现这种外观所需的样式。
刷子
这些样式中有许多画笔设置,都是Property="{StaticResource Media_...}"
. 我现在将省略定义,因为编译它们需要一些时间,但如果有人有兴趣复制我使用的确切颜色,请发表评论。
排序箭头样式
(箭头本身包含在列标题样式中)
<Style
x:Key="DataGrid_ArrowStyle"
TargetType="Polygon">
<Setter
Property="Grid.Column"
Value="1" />
<Setter
Property="HorizontalAlignment"
Value="Right" />
<Setter
Property="VerticalAlignment"
Value="Bottom" />
<Setter
Property="StrokeThickness"
Value="1" />
<Setter
Property="Stroke"
Value="{StaticResource Media_BrightGraphicBorderBrush}" />
<Setter
Property="Fill"
Value="{StaticResource Media_BrightGraphicBackgroundBrush}" />
<Setter
Property="Visibility"
Value="Hidden" />
</Style>
列标题拇指样式
(拇指本身包含在列标题样式中)
<Style
x:Key="DataGrid_ColumnHeaderThumbStyle"
TargetType="Thumb">
<Setter
Property="Width"
Value="8" />
<Setter
Property="Background"
Value="{StaticResource Media_RaisedSeparatorBackgroundBrush}" />
<Setter
Property="Cursor"
Value="SizeWE" />
<Setter
Property="Template">
<Setter.Value>
<ControlTemplate
TargetType="Thumb">
<Border
Padding="{TemplateBinding Padding}"
Background="Transparent">
<Border
Padding="0,2,0,2">
<Rectangle
HorizontalAlignment="Center"
Width="2"
Fill="{TemplateBinding Background}" />
</Border>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
列标题样式
(指的是上面定义的排序箭头样式和列标题拇指样式)
<Style
x:Key="DataGrid_ColumnHeaderStyle"
TargetType="wt:DataGridColumnHeader">
<Setter
Property="Padding"
Value="5,2,3,3" />
<Setter
Property="HorizontalContentAlignment"
Value="Stretch" />
<Setter
Property="VerticalContentAlignment"
Value="Stretch" />
<Setter
Property="FontWeight"
Value="Bold" />
<Setter
Property="BorderBrush"
Value="{StaticResource Media_RaisedBorderBrush}" />
<Setter
Property="Background"
Value="{StaticResource Media_RaisedBackgroundBrush}" />
<Setter
Property="Foreground"
Value="{StaticResource Media_RaisedForegroundBrush}" />
<Setter
Property="SeparatorBrush"
Value="{StaticResource Media_RaisedBorderBrush}" />
<Setter
Property="SeparatorVisibility"
Value="Visible" />
<Setter
Property="Template">
<Setter.Value>
<ControlTemplate
TargetType="wt:DataGridColumnHeader">
<Grid>
<wt:DataGridHeaderBorder
Name="HeaderBorder"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}"
SortDirection="{TemplateBinding SortDirection}"
IsClickable="{TemplateBinding CanUserSort}"
IsHovered="{TemplateBinding IsMouseOver}"
IsPressed="{TemplateBinding IsPressed}"
SeparatorVisibility="{TemplateBinding SeparatorVisibility}"
SeparatorBrush="{TemplateBinding SeparatorBrush}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition
Width="*" />
<ColumnDefinition
Width="12" />
</Grid.ColumnDefinitions>
<ContentPresenter
Name="HeaderContent"
Grid.Column="0"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
ContentStringFormat="{TemplateBinding ContentStringFormat}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}" />
<Polygon
Name="UpArrow"
Style="{StaticResource DataGrid_ArrowStyle}"
Margin="0,0,0,2"
Points="0,0 8,0 4,-6 0,0" />
<Polygon
Name="DownArrow"
Margin="0,0,0,1"
Style="{StaticResource DataGrid_ArrowStyle}"
Points="0,0 8,0 4,5 0,0" />
</Grid>
</wt:DataGridHeaderBorder>
<Thumb
x:Name="PART_LeftHeaderGripper"
Style="{StaticResource DataGrid_ColumnHeaderThumbStyle}"
Margin="-4,0,0,0"
HorizontalAlignment="Left" />
<Thumb
x:Name="PART_RightHeaderGripper"
Style="{StaticResource DataGrid_ColumnHeaderThumbStyle}"
Margin="0,0,-4,0"
HorizontalAlignment="Right"></Thumb>
</Grid>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition
Property="CanUserSort"
Value="True" />
<Condition
Property="IsMouseOver"
Value="True" />
</MultiTrigger.Conditions>
<Setter
TargetName="HeaderBorder"
Property="TextBlock.Foreground"
Value="{StaticResource Media_MousedOverForegroundBrush}" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition
Property="CanUserSort"
Value="True" />
<Condition
Property="IsPressed"
Value="True" />
</MultiTrigger.Conditions>
<Setter
TargetName="HeaderBorder"
Property="BorderBrush"
Value="{StaticResource Media_PressedBorderBrush}" />
<Setter
TargetName="HeaderBorder"
Property="Background"
Value="{StaticResource Media_PressedBackgroundBrush}" />
<Setter
TargetName="HeaderBorder"
Property="TextBlock.Foreground"
Value="{StaticResource Media_PressedForegroundBrush}" />
</MultiTrigger>
<Trigger
Property="SortDirection"
Value="Ascending">
<Setter
TargetName="UpArrow"
Property="Visibility"
Value="Visible" />
</Trigger>
<Trigger
Property="SortDirection"
Value="Descending">
<Setter
TargetName="DownArrow"
Property="Visibility"
Value="Visible" />
</Trigger>
<Trigger
Property="CanUserSort"
Value="False">
<Setter
TargetName="HeaderContent"
Property="Grid.ColumnSpan"
Value="2" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition
Property="HorizontalContentAlignment"
Value="Center" />
<Condition
Property="CanUserSort"
Value="True" />
</MultiTrigger.Conditions>
<Setter
TargetName="HeaderContent"
Property="Grid.ColumnSpan"
Value="2" />
<Setter
TargetName="HeaderContent"
Property="Margin"
Value="12,0,12,0" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
居中的列标题样式
(使用它使标题居中;如果列是可排序的,将自动为排序箭头腾出空间)
<Style
x:Key="DataGrid_CenteredColumnHeaderStyle"
TargetType="wt:DataGridColumnHeader"
BasedOn="{StaticResource DataGrid_ColumnHeaderStyle}">
<Setter
Property="HorizontalContentAlignment"
Value="Center" />
</Style>
包装列标题样式
(使用它来允许标题的文本自动换行 - 仅当您手动设置宽度或用户手动缩小列时才有效)
<Style
x:Key="DataGrid_WrappingColumnHeaderStyle"
TargetType="wt:DataGridColumnHeader"
BasedOn="{StaticResource DataGrid_ColumnHeaderStyle}">
<Setter
Property="VerticalContentAlignment"
Value="Top" />
<Setter
Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock
TextWrapping="WrapWithOverflow"
Text="{TemplateBinding Content}" />
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
单元格样式
<Style
x:Key="DataGrid_CellStyle"
TargetType="wt:DataGridCell">
<Setter
Property="Padding"
Value="5,2,5,2" />
<Setter
Property="BorderThickness"
Value="1" />
<Setter
Property="BorderBrush"
Value="Transparent" />
<Setter
Property="Background"
Value="Transparent" />
<Setter
Property="Template">
<Setter.Value>
<ControlTemplate
TargetType="wt:DataGridCell">
<Border
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
SnapsToDevicePixels="True"
Padding="{TemplateBinding Padding}">
<ContentPresenter
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentStringFormat="{TemplateBinding ContentStringFormat}"
Content="{TemplateBinding Content}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger
Property="IsSelected"
Value="True">
<Setter
Property="BorderBrush"
Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
<Setter
Property="Background"
Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
<Setter
Property="Foreground"
Value="Black" />
</Trigger>
<Trigger
Property="IsKeyboardFocusWithin"
Value="True">
<Setter
Property="BorderBrush"
Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
<Setter
Property="Background"
Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
<Setter
Property="Foreground"
Value="Black" />
<!--<Setter
Property="BorderBrush"
Value="{DynamicResource {ComponentResourceKey ResourceId=FocusBorderBrushKey, TypeInTargetAssembly=wt:DataGrid}}" />-->
</Trigger>
</Style.Triggers>
</Style>
居中单元格样式
(使用它来使单元格的内容居中)
<Style
x:Key="DataGrid_CenteredCellStyle"
TargetType="wt:DataGridCell"
BasedOn="{StaticResource DataGrid_CellStyle}">
<Setter
Property="HorizontalContentAlignment"
Value="Center" />
</Style>
数据网格样式
(为许多属性建立一组默认值,包括上面定义的列标题样式和单元格样式)
<Style
x:Key="DataGrid_Style"
TargetType="wt:DataGrid">
<Setter
Property="ColumnHeaderStyle"
Value="{StaticResource DataGrid_ColumnHeaderStyle}" />
<Setter
Property="CellStyle"
Value="{StaticResource DataGrid_CellStyle}" />
<Setter
Property="RowBackground"
Value="{StaticResource Media_OddRowBackgroundBrush}" />
<Setter
Property="AlternatingRowBackground"
Value="{StaticResource Media_EvenRowBackgroundBrush}" />
<Setter
Property="HorizontalGridLinesBrush"
Value="LightGray" />
<Setter
Property="VerticalGridLinesBrush"
Value="LightGray" />
<Setter
Property="SelectionMode"
Value="Single" />
<Setter
Property="SelectionUnit"
Value="FullRow" />
<Setter
Property="AutoGenerateColumns"
Value="False" />
<Setter
Property="CanUserAddRows"
Value="False" />
<Setter
Property="CanUserDeleteRows"
Value="False" />
<Setter
Property="CanUserReorderColumns"
Value="True" />
<Setter
Property="CanUserResizeColumns"
Value="True" />
<Setter
Property="CanUserResizeRows"
Value="False" />
<Setter
Property="CanUserSortColumns"
Value="True" />
<Setter
Property="IsReadOnly"
Value="True" />
<Setter
Property="HeadersVisibility"
Value="Column" />
</Style>
使用这些样式的示例 DataGrid
(注意:需要支持数据——一个 XML 文件——才能工作)
<wt:DataGrid
Style="{StaticResource DataGrid_Style}"
Margin="0,5,0,0"
ItemsSource="{Binding Source={StaticResource Main_ContactData}, XPath=//Contacts/*}">
<wt:DataGrid.Columns>
<wt:DataGridTextColumn
Binding="{Binding XPath=@Letter}"
Header="ID" />
<wt:DataGridTextColumn
Binding="{Binding XPath=@Name}"
Header="Name" />
<wt:DataGridTextColumn
HeaderStyle="{StaticResource DataGrid_CenteredColumnHeaderStyle}"
CellStyle="{StaticResource DataGrid_CenteredCellStyle}"
Binding="{Binding XPath=@IsSaved}"
Header="Saved?" />
<wt:DataGridTextColumn
HeaderStyle="{StaticResource DataGrid_CenteredColumnHeaderStyle}"
CellStyle="{StaticResource DataGrid_CenteredCellStyle}"
Binding="{Binding XPath=@IsBackedUp}"
Header="Backed Up?" />
</wt:DataGrid.Columns>
</wt:DataGrid>