需要有关WPF中自定义样式的帮助

时间:2021-07-18 07:45:33

I'm attempting to build some simple custom styles for the WPF Toolkit DataGrid control.

我正在尝试为WPF Toolkit DataGrid控件构建一些简单的自定义样式。

I have a style for the overall DataGrid and a style for the DataGridColumnHeader. I am not setting any control templates, only basic properties.

我有一个整体DataGrid的样式和DataGridColumnHeader的样式。我没有设置任何控件模板,只有基本属性。

Here is what my sample DataGrid looks like with my custom styling applied:

以下是我的示例DataGrid在应用自定义样式时的样子:

alt text http://img86.imageshack.us/img86/43/datagridcustomstyle.jpg

alt text http://img86.imageshack.us/img86/43/datagridcustomstyle.jpg

The header has the gradient blue background, bold text, padding, etc. I want, but two things have disappeared: the separators between the column headers and the sort arrow for the ID column (this column currently has a descending sort on it).

标题有渐变蓝色背景,粗体文本,填充等我想要,但有两件事已经消失:列标题之间的分隔符和ID列的排序箭头(此列当前对其进行降序排序)。

Why would the separators and sort arrow disappear if I have not messed with any control templates?

如果我没有搞乱任何控件模板,为什么分隔符和排序箭头会消失?

I even tried explicitly setting the SeparatorBrush to Black and the SeparatorVisibility to Visible, but this had no effect.

我甚至尝试将SeparatorBrush明确设置为Black,将SeparatorVisibility设置为Visible,但这没有效果。

Here is what my sample DataGrid looks like if I revert back to the default styling:

这是我的示例DataGrid,如果我恢复到默认样式:

alt text http://img42.imageshack.us/img42/6533/datagriddefaultstyle.jpg

替代文字http://img42.imageshack.us/img42/6533/datagriddefaultstyle.jpg

The separators and sort arrow are back, so it is definitely my style that is making the difference.

分隔符和排序箭头都回来了,所以绝对是我的风格正在发挥作用。

Here is my custom DataGridColumnHeader style

这是我的自定义DataGridColumnHeader样式

<Style
    x:Key="DataGrid_ColumnHeaderStyle"
    TargetType="wt:DataGridColumnHeader">
    <Setter
        Property="Padding"
        Value="5,2,5,2" />
    <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="Black" />
    <Setter
        Property="SeparatorVisibility"
        Value="Visible" />
</Style>

Here is my custom DataGrid style

这是我的自定义DataGrid样式

<Style
    x:Key="DataGrid_Style"
    TargetType="wt:DataGrid">
    <Setter
        Property="ColumnHeaderStyle"
        Value="{StaticResource DataGrid_ColumnHeaderStyle}" />
    <Setter
        Property="RowBackground"
        Value="{StaticResource Media_OddRowBackgroundBrush}" />
    <Setter
        Property="AlternatingRowBackground"
        Value="{StaticResource Media_EvenRowBackgroundBrush}" />
    <Setter
        Property="HorizontalGridLinesBrush"
        Value="White" />
    <Setter
        Property="VerticalGridLinesBrush"
        Value="LightGray" />
    <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" />
</Style>

Here is the markup for my sample DataGrid

这是我的示例DataGrid的标记

<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
            Binding="{Binding XPath=@IsSaved}"
            Header="Saved?" />
        <wt:DataGridTextColumn
            Binding="{Binding XPath=@IsBackedUp}"
            Header="Backed Up?" />
    </wt:DataGrid.Columns>
</wt:DataGrid>

Is this a bug?

这是一个错误吗?

If not, can you please advise me on how to modify my styles so that I don't lose the separator lines and sort arrow?

如果没有,你能告诉我如何修改我的样式,这样我就不会丢失分隔线和排序箭头吗?

Edit

I tried adding BasedOn attributes per @Aran's suggestion (below), but this didn't seem to have any effect. Anyone have any other thoughts?

我尝试按照@Aran的建议添加了BasedOn属性(如下),但这似乎没有任何影响。有没有其他想法?

2 个解决方案

#1


5  

Thanks to @Aran's answer as well as a couple posts I found in Codeplex Discussions (see http://wpf.codeplex.com/Thread/View.aspx?ThreadId=65069), I managed to come up with a set of styles that allows the background of the header row to be set without giving up functionality (sort arrows, separators, etc.).

感谢@Aran的回答以及我在Codeplex Discussions中发现的一些帖子(请参阅http://wpf.codeplex.com/Thread/View.aspx?ThreadId=65069),我设法提出了一系列样式允许设置标题行的背景而不放弃功能(排序箭头,分隔符等)。

The one exception to this is the "cell selection" feature. DataGrid has a SelectionUnit property, which can be set to Cell, FullRow, or CellOrRowHeader, but it doesn't seem to work. If I set it to FullRow (which is supposed to only select the whole row no matter where you click on that row), it still visually selects individual cells when you click on them. The image below shows an example of a DataGrid (with no styling applied) where SelectionUnit="FullRow". As you can see, it sure looks like there is a cell selected (the G row of the Name column). Since I don't currently need cell selection, I designed my styles to suppress this dark black border that appears around the cell when it's clicked.

一个例外是“细胞选择”功能。 DataGrid有一个SelectionUnit属性,可以设置为Cell,FullRow或CellOrRowHeader,但它似乎不起作用。如果我将它设置为FullRow(它应该只选择整行,无论你在哪一行点击),当你点击它们时它仍然可以直观地选择单个单元格。下图显示了一个DataGrid(未应用样式)的示例,其中SelectionUnit =“FullRow”。正如您所看到的,确实看起来已经选择了一个单元格(Name列的G行)。由于我目前不需要选择单元格,因此我设计了自己的样式来抑制单击单元格时出现的深黑色边框。

alt text http://img80.imageshack.us/img80/4757/datagriddefaultcellsele.jpg

替代文字http://img80.imageshack.us/img80/4757/datagriddefaultcellsele.jpg

Here is an example of a styled DataGrid sorted descending by ID. As you can see, the down arrow appears next to the ID label, and the column is appropriately auto-sized to make room for the sort arrow.

下面是按ID排序的样式化DataGrid示例。如您所见,ID标签旁边会出现向下箭头,并且该列的大小适当,以便为排序箭头腾出空间。

alt text http://img377.imageshack.us/img377/3836/datagridcustomfixed.jpg

替代文字http://img377.imageshack.us/img377/3836/datagridcustomfixed.jpg

Here is another example of a styled DataGrid. This one is sorted ascending by "Saved?". Notice that the heading is centered, yet it still leaves enough room on either side for the sort arrow.

这是样式化DataGrid的另一个示例。这个按升序排序“已保存?”。请注意,标题是居中的,但它仍然为排序箭头留下足够的空间。

alt text http://img203.imageshack.us/img203/5140/datagridcustomfixed2.jpg

替代文字http://img203.imageshack.us/img203/5140/datagridcustomfixed2.jpg


Here are the styles necessary to achieve this look.

Brushes

There are a number of brush settings in these styles, all of the form Property="{StaticResource Media_...}". I'm going to leave out the definitions for now because it would take me some time to compile them all, but if anyone is interested in duplicating the exact colors I used, leave a comment.

这些样式中有许多画笔设置,所有形式都是Property =“{StaticResource Media _...}”。我现在要省略这些定义,因为我需要一些时间来编译它们,但如果有人有兴趣复制我使用的确切颜色,请发表评论。

Sort Arrow Style

排序箭头样式

(the arrows themselves are contained in the Column Header Style)

(箭头本身包含在列标题样式中)

<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>

Column Header Thumb Style

列标题缩略图样式

(the thumbs themselves are contained in the Column Header 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>

Column Header Style

列标题样式

(refers to the Sort Arrow Style and the Column Header Thumb Style defined above)

(指上面定义的排序箭头样式和列标题缩略图样式)

<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>

Centered Column Header Style

中心列标题样式

(use this to center a header; will automatically make room for a sort arrow if the column is sortable)

(使用此选项将标题置于中心;如果列可排序,将自动为排序箭头腾出空间)

<Style
    x:Key="DataGrid_CenteredColumnHeaderStyle"
    TargetType="wt:DataGridColumnHeader"
    BasedOn="{StaticResource DataGrid_ColumnHeaderStyle}">
    <Setter
        Property="HorizontalContentAlignment"
        Value="Center" />
</Style>

Wrapping Column Header Style

包裹列标题样式

(use this to allow the text for a header to word-wrap--only works if you set the width manually or the user manually shrinks the column)

(使用此选项允许标题的文本自动换行 - 仅在手动设置宽度或用户手动缩小列时才有效)

<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>

Cell 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>

Centered Cell Style

中心细胞样式

(use this to center the contents of a cell)

(用它来居中细胞的内容)

<Style
    x:Key="DataGrid_CenteredCellStyle"
    TargetType="wt:DataGridCell"
    BasedOn="{StaticResource DataGrid_CellStyle}">
    <Setter
        Property="HorizontalContentAlignment"
        Value="Center" />
</Style>

Data Grid Style

数据网格样式

(establishes a set of default values for a number of properties, including the Column Header Style and Cell Style, which are defined above)

(为多个属性建立一组默认值,包括上面定义的列标题样式和单元格样式)

<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>

Example DataGrid using these styles

示例DataGrid使用这些样式

(note: requires backing data--an XML file--to work)

(注意:要求支持数据 - 一个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>

#2


3  

try putting

<Style
  x:Key="DataGrid_Style"
  TargetType="wt:DataGrid"
  BasedOn="{StaticResource {x:Type wt:DataGrid}}">

to base your style on the current datagrid one, and the same for the headers

将您的样式基于当前数据网格,并且标题相同

<Style
  x:Key="DataGrid_ColumnHeaderStyle"
  TargetType="wt:DataGridColumnHeader"
  BasedOn="{StaticResource {x:Type wt:DataGridColumnHeader}}">

scratch the above - i pulled your style down to the offending element

划伤上面 - 我把你的风格拉到了令人讨厌的元素

   <Style
     TargetType="wt:DataGridColumnHeader"
     BasedOn="{StaticResource {x:Type wt:DataGridColumnHeader}}">
     <Setter
        Property="Background"
        Value="Blue" />
  </Style>

if you set the background (or the border brush ) you're screwed.

如果你设置背景(或边框画笔),你就搞砸了。

I found this link on code project, to back this up -

我在代码项目中找到了这个链接,以支持它 -

"The style of the column header can easily be modified via the ColumnHeaderStyle of the DataGrid. However, if you modify the background colour of the column header, you will find that the sort arrows disappear! This is because the arrows are not part of the ColumnHeader template; instead, they are added programmatically."

“可以通过DataGrid的ColumnHeaderStyle轻松修改列标题的样式。但是,如果修改列标题的背景颜色,您会发现排序箭头消失!这是因为箭头不是ColumnHeader模板;相反,它们是以编程方式添加的。“

he has a style that re-adds the sort indicators.

他有一种重新添加排序指标的风格。

i have had a look at the code for DataGridHeaderBorder (which is the border of the datagridrowheader) which does not have its own control template, it simply derives from border. As well as the seperators being added programatically (the separators are just rectangles see line 1199 of DataGridHeaderBorder.cs) the sort indicators are. the brief look at the code that i had would suggest they should still get drawn but they dont, a step thru of the code is in order.

我已经看过DataGridHeaderBorder的代码(它是datagridrowheader的边框),它没有自己的控件模板,只是从边框派生。除了以编程方式添加的分隔符(分隔符只是矩形,请参见DataGridHeaderBorder.cs的第1199行),排序指示符也是如此。简要看一下我所拥有的代码会建议它们仍然应该被绘制但是它们不会,代码的一步到位。

The solution is to override the control template i think, and add them yourself, the link on code project will get you started.

解决方案是覆盖我认为的控件模板,并自己添加它们,代码项目上的链接将帮助您入门。

#1


5  

Thanks to @Aran's answer as well as a couple posts I found in Codeplex Discussions (see http://wpf.codeplex.com/Thread/View.aspx?ThreadId=65069), I managed to come up with a set of styles that allows the background of the header row to be set without giving up functionality (sort arrows, separators, etc.).

感谢@Aran的回答以及我在Codeplex Discussions中发现的一些帖子(请参阅http://wpf.codeplex.com/Thread/View.aspx?ThreadId=65069),我设法提出了一系列样式允许设置标题行的背景而不放弃功能(排序箭头,分隔符等)。

The one exception to this is the "cell selection" feature. DataGrid has a SelectionUnit property, which can be set to Cell, FullRow, or CellOrRowHeader, but it doesn't seem to work. If I set it to FullRow (which is supposed to only select the whole row no matter where you click on that row), it still visually selects individual cells when you click on them. The image below shows an example of a DataGrid (with no styling applied) where SelectionUnit="FullRow". As you can see, it sure looks like there is a cell selected (the G row of the Name column). Since I don't currently need cell selection, I designed my styles to suppress this dark black border that appears around the cell when it's clicked.

一个例外是“细胞选择”功能。 DataGrid有一个SelectionUnit属性,可以设置为Cell,FullRow或CellOrRowHeader,但它似乎不起作用。如果我将它设置为FullRow(它应该只选择整行,无论你在哪一行点击),当你点击它们时它仍然可以直观地选择单个单元格。下图显示了一个DataGrid(未应用样式)的示例,其中SelectionUnit =“FullRow”。正如您所看到的,确实看起来已经选择了一个单元格(Name列的G行)。由于我目前不需要选择单元格,因此我设计了自己的样式来抑制单击单元格时出现的深黑色边框。

alt text http://img80.imageshack.us/img80/4757/datagriddefaultcellsele.jpg

替代文字http://img80.imageshack.us/img80/4757/datagriddefaultcellsele.jpg

Here is an example of a styled DataGrid sorted descending by ID. As you can see, the down arrow appears next to the ID label, and the column is appropriately auto-sized to make room for the sort arrow.

下面是按ID排序的样式化DataGrid示例。如您所见,ID标签旁边会出现向下箭头,并且该列的大小适当,以便为排序箭头腾出空间。

alt text http://img377.imageshack.us/img377/3836/datagridcustomfixed.jpg

替代文字http://img377.imageshack.us/img377/3836/datagridcustomfixed.jpg

Here is another example of a styled DataGrid. This one is sorted ascending by "Saved?". Notice that the heading is centered, yet it still leaves enough room on either side for the sort arrow.

这是样式化DataGrid的另一个示例。这个按升序排序“已保存?”。请注意,标题是居中的,但它仍然为排序箭头留下足够的空间。

alt text http://img203.imageshack.us/img203/5140/datagridcustomfixed2.jpg

替代文字http://img203.imageshack.us/img203/5140/datagridcustomfixed2.jpg


Here are the styles necessary to achieve this look.

Brushes

There are a number of brush settings in these styles, all of the form Property="{StaticResource Media_...}". I'm going to leave out the definitions for now because it would take me some time to compile them all, but if anyone is interested in duplicating the exact colors I used, leave a comment.

这些样式中有许多画笔设置,所有形式都是Property =“{StaticResource Media _...}”。我现在要省略这些定义,因为我需要一些时间来编译它们,但如果有人有兴趣复制我使用的确切颜色,请发表评论。

Sort Arrow Style

排序箭头样式

(the arrows themselves are contained in the Column Header Style)

(箭头本身包含在列标题样式中)

<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>

Column Header Thumb Style

列标题缩略图样式

(the thumbs themselves are contained in the Column Header 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>

Column Header Style

列标题样式

(refers to the Sort Arrow Style and the Column Header Thumb Style defined above)

(指上面定义的排序箭头样式和列标题缩略图样式)

<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>

Centered Column Header Style

中心列标题样式

(use this to center a header; will automatically make room for a sort arrow if the column is sortable)

(使用此选项将标题置于中心;如果列可排序,将自动为排序箭头腾出空间)

<Style
    x:Key="DataGrid_CenteredColumnHeaderStyle"
    TargetType="wt:DataGridColumnHeader"
    BasedOn="{StaticResource DataGrid_ColumnHeaderStyle}">
    <Setter
        Property="HorizontalContentAlignment"
        Value="Center" />
</Style>

Wrapping Column Header Style

包裹列标题样式

(use this to allow the text for a header to word-wrap--only works if you set the width manually or the user manually shrinks the column)

(使用此选项允许标题的文本自动换行 - 仅在手动设置宽度或用户手动缩小列时才有效)

<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>

Cell 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>

Centered Cell Style

中心细胞样式

(use this to center the contents of a cell)

(用它来居中细胞的内容)

<Style
    x:Key="DataGrid_CenteredCellStyle"
    TargetType="wt:DataGridCell"
    BasedOn="{StaticResource DataGrid_CellStyle}">
    <Setter
        Property="HorizontalContentAlignment"
        Value="Center" />
</Style>

Data Grid Style

数据网格样式

(establishes a set of default values for a number of properties, including the Column Header Style and Cell Style, which are defined above)

(为多个属性建立一组默认值,包括上面定义的列标题样式和单元格样式)

<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>

Example DataGrid using these styles

示例DataGrid使用这些样式

(note: requires backing data--an XML file--to work)

(注意:要求支持数据 - 一个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>

#2


3  

try putting

<Style
  x:Key="DataGrid_Style"
  TargetType="wt:DataGrid"
  BasedOn="{StaticResource {x:Type wt:DataGrid}}">

to base your style on the current datagrid one, and the same for the headers

将您的样式基于当前数据网格,并且标题相同

<Style
  x:Key="DataGrid_ColumnHeaderStyle"
  TargetType="wt:DataGridColumnHeader"
  BasedOn="{StaticResource {x:Type wt:DataGridColumnHeader}}">

scratch the above - i pulled your style down to the offending element

划伤上面 - 我把你的风格拉到了令人讨厌的元素

   <Style
     TargetType="wt:DataGridColumnHeader"
     BasedOn="{StaticResource {x:Type wt:DataGridColumnHeader}}">
     <Setter
        Property="Background"
        Value="Blue" />
  </Style>

if you set the background (or the border brush ) you're screwed.

如果你设置背景(或边框画笔),你就搞砸了。

I found this link on code project, to back this up -

我在代码项目中找到了这个链接,以支持它 -

"The style of the column header can easily be modified via the ColumnHeaderStyle of the DataGrid. However, if you modify the background colour of the column header, you will find that the sort arrows disappear! This is because the arrows are not part of the ColumnHeader template; instead, they are added programmatically."

“可以通过DataGrid的ColumnHeaderStyle轻松修改列标题的样式。但是,如果修改列标题的背景颜色,您会发现排序箭头消失!这是因为箭头不是ColumnHeader模板;相反,它们是以编程方式添加的。“

he has a style that re-adds the sort indicators.

他有一种重新添加排序指标的风格。

i have had a look at the code for DataGridHeaderBorder (which is the border of the datagridrowheader) which does not have its own control template, it simply derives from border. As well as the seperators being added programatically (the separators are just rectangles see line 1199 of DataGridHeaderBorder.cs) the sort indicators are. the brief look at the code that i had would suggest they should still get drawn but they dont, a step thru of the code is in order.

我已经看过DataGridHeaderBorder的代码(它是datagridrowheader的边框),它没有自己的控件模板,只是从边框派生。除了以编程方式添加的分隔符(分隔符只是矩形,请参见DataGridHeaderBorder.cs的第1199行),排序指示符也是如此。简要看一下我所拥有的代码会建议它们仍然应该被绘制但是它们不会,代码的一步到位。

The solution is to override the control template i think, and add them yourself, the link on code project will get you started.

解决方案是覆盖我认为的控件模板,并自己添加它们,代码项目上的链接将帮助您入门。