5

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

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

这是应用了我的自定义样式后我的示例 DataGrid 的样子:

替代文字 http://img86.imageshack.us/img86/43/datagridcustomstyle.jpg

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

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

我什至尝试明确设置SeparatorBrushtoBlackSeparatorVisibilityto Visible,但这没有效果。

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

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

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

这是我的自定义 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>

这是我的自定义 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>

这是我的示例 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>

这是一个错误吗?

如果没有,您能否告诉我如何修改我的样式,以免丢失分隔线和排序箭头?

编辑

我尝试BasedOn根据@Aran 的建议添加属性(如下),但这似乎没有任何效果。有人有其他想法吗?

4

2 回答 2

5

感谢@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>
于 2009-10-16T19:53:43.837 回答
4

试着把

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

将您的样式基于当前的数据网格之一,对于标题也是如此

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

从上面划掉-我把你的风格拉到了有问题的地方

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

如果你设置背景(或边框画笔)你就完蛋了。

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

“通过DataGrid的ColumnHeaderStyle可以很方便的修改列头的样式。但是,如果修改列头的背景色,你会发现排序箭头消失了!这是因为箭头不属于ColumnHeader 模板;相反,它们是以编程方式添加的。”

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

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

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

于 2009-10-15T02:30:46.020 回答