如何在应用Column标题的背景后添加排序箭头

时间:2010-12-20 07:53:25

标签: wpf silverlight wpfdatagrid

将背景颜色应用于列标题后,缺少排序箭头。如何添加回来?

3 个答案:

答案 0 :(得分:40)

我认为你将不得不重新模板化DataGridColumnHeader并从那里添加它。这是一个例子。您将不得不添加对PresentationFramework.Aero

的引用
xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"

<DataGrid ...>
    <DataGrid.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 TargetType="{x:Type DataGridColumnHeader}">
            <Setter Property="Background" Value="Blue"/>
            <Setter Property="BorderBrush" Value="Red"/>
            <Setter Property="BorderThickness" Value="1,1,1,1"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
                        <Grid>
                            <Themes:DataGridHeaderBorder 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}">
                                <Grid>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto"/>
                                        <ColumnDefinition Width="*"/>
                                    </Grid.ColumnDefinitions>
                                    <ContentPresenter Grid.Column="0" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                                    <Path x:Name="SortArrow"
                                            Grid.Column="1"
                                            HorizontalAlignment="Right" VerticalAlignment="Center"                                           
                                            Width="8" Height="6" Margin="2,0,5,0"
                                            Stretch="Fill" Opacity="0.5" Fill="White"
                                            RenderTransformOrigin="0.5,0.4"
                                            Visibility="Collapsed"
                                            Data="M0,0 L1,0 0.5,1 z" />
                                </Grid>
                            </Themes:DataGridHeaderBorder>
                            <Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left" Style="{StaticResource ColumnHeaderGripperStyle}"/>
                            <Thumb x:Name="PART_RightHeaderGripper" HorizontalAlignment="Right" Style="{StaticResource ColumnHeaderGripperStyle}"/>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="SortDirection" Value="Ascending">
                                <Setter TargetName="SortArrow" Property="Visibility" Value="Visible" />
                                <Setter TargetName="SortArrow" Property="RenderTransform">
                                    <Setter.Value>
                                        <RotateTransform Angle="180" />
                                    </Setter.Value>
                                </Setter>
                            </Trigger>
                            <Trigger Property="SortDirection" Value="Descending">
                                <Setter TargetName="SortArrow" Property="Visibility" Value="Visible" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </DataGrid.Resources>
</DataGrid>

答案 1 :(得分:3)

这是一篇博客文章,很好地细分了DataGridColumnHeader的模板过程,并提供了结果的视觉效果。 Blog post by Terry Hutt

他演示了默认的列标题。单击列标题以重新排序列。您还可以通过拖动标题来重新排序列,并通过在标题的任一端拖动隐藏的拇指来调整列的大小。标题本身显然是一个在文本上方带有可选排序指示符的按钮。看起来很讨厌。

让我们尝试更改标题的背景,以免它不是按钮。 DataGrid具有ColumnHeaderStyle属性。我们可以使用它,但为简单起见,我们将其添加到XAML中,为列标题创建默认样式...

<Window.Resources>
    <Style TargetType="{x:Type DataGridColumnHeader}">
        <Setter Property="Background" Value="LightGray"/>
    </Style>
</Window.Resources>

如果使用新样式运行项目,则标题看起来会好得多。但是,等等-我们的排序指示器在哪里?事实证明,DataGridColumnHeader的样式是故意的,因此如果更改背景颜色,则排序指示器将隐藏。有时,我只是不了解Microsoft的业务方式。当开发人员尝试修复该控件时,为什么要设置这种难看的控件的样式,然后破坏其他关键功能。

我们必须重新模板化DataGridColumnHeader。当我们在那里时,让我们一起玩吧!这就是我们要做的...

更改背景颜色 使用边框创建下划线 鼠标悬停在标题上方时更改边框的颜色 将排序指示器移到标题文本的侧面而不是上方 使列宽的拇指不可见,但在其上方时更改光标

第1步-增强样式,使其看起来像这样...

<Style TargetType="{x:Type DataGridColumnHeader}">
    <Setter Property="SnapsToDevicePixels" Value="True"/>
    <Setter Property="MinWidth" Value="0"/>
    <Setter Property="MinHeight" Value="0"/>
    <Setter Property="Foreground" Value="Black"/>
    <Setter Property="Background" Value="LightGray"/>
    <Setter Property="Cursor" Value="Hand"/>
</Style>

第2步-编写ControlTemplate,用于定义标题区域,排序指示器,边框和拇指。网格控制标题的布局,左侧是“内容”区域,右侧是“排序指示器”。注意,排序指示符是使用路径定义的。这两个矩形为列标题产生了可见的左右边缘。必须定义“缩略图”,并允许用户调整列的大小。稍后我们将定义ThumbStyle。注意边界的名称。我们需要它,因此我们可以在步骤3中使用触发器对其进行更改。将其添加到结束样式标签之前。

<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="Auto"/>
                </Grid.ColumnDefinitions>
                <Border x:Name="BackgroundBorder" BorderThickness="0,0,0,2"
                        Background="LightGray"
                        BorderBrush="Black"
                        Grid.ColumnSpan="2"/>
                <ContentPresenter Margin="6,3,6,3" VerticalAlignment="Center"/>
                <Path x:Name="SortArrow" Visibility="Collapsed" Data="M 0,0 L 1,0 0.5,1 z" Stretch="Fill"
                     Grid.Column="1" Width="8" Height="6" Fill="Black" Margin="0,0,8,0"
                      VerticalAlignment="Center" RenderTransformOrigin="0.5, 0.4"/>
                <Rectangle Width="1" Fill="#EEEEEE" HorizontalAlignment="Right" Grid.ColumnSpan="2"/>
                <Rectangle Width="1" Margin="0,0,1,0" Fill="#DDDDDD" HorizontalAlignment="Right" Grid.ColumnSpan="2"/>
                <Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left" Style="{StaticResource ThumbStyle}"/>
                <Thumb x:Name="PART_RightHeaderGripper" Grid.Column="1" HorizontalAlignment="Right" Style="{StaticResource ThumbStyle}"/>
            </Grid>
        </ControlTemplate>
    </Setter.Value>
</Setter>

第3步-添加触发器以在鼠标移至列标题上方时更改边框的颜色。在“网格关闭”标签之后添加以下触发器。

<ControlTemplate.Triggers>
    <Trigger Property="IsMouseOver" Value="True">
        <Setter TargetName="BackgroundBorder" Property="Background" Value="LightGray"/>
        <Setter TargetName="BackgroundBorder" Property="BorderBrush" Value="Orange"/>
    </Trigger>
</ControlTemplate.Triggers>

步骤4 -添加触发器以在对列进行排序时显示和/或旋转“排序指示器”。

<Trigger Property="SortDirection" Value="Ascending">
    <Setter TargetName="SortArrow" Property="Visibility" Value="Visible"/>
    <Setter TargetName="SortArrow" Property="RenderTransform">
        <Setter.Value>
            <RotateTransform Angle="180"/>
        </Setter.Value>
    </Setter>
</Trigger>
<Trigger Property="SortDirection" Value="Descending">
    <Setter TargetName="SortArrow" Property="Visibility" Value="Visible"/>
</Trigger>

步骤5 -隐藏第0列中的LeftHeaderGripper-我们不需要它。

<Trigger Property="DisplayIndex" Value="0">
    <Setter TargetName="PART_LeftHeaderGripper" Property="Visibility" Value="Collapsed"/>
</Trigger>

如所承诺的,这是ThumbStyle定义。将其插入DataGridColumnHeader样式上方。我使用带有SizeWE光标的不可见矩形。您可以选择颜色或使用完全不同的东西。

<Style TargetType="{x:Type Thumb}" x:Key="ThumbStyle">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Thumb}">
                <Rectangle Width="1" Stroke="Transparent" Cursor="SizeWE"/>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Display result

答案 2 :(得分:0)

可能有更好的解决方案,但我只是根据排序方向将字符▴或append附加到了列标题。