【问题标题】:How to add back the sort arrow after applying background of Column headers如何在应用列标题背景后添加回排序箭头
【发布时间】:2011-05-28 03:08:36
【问题描述】:

将背景颜色应用于列标题后,排序箭头丢失。怎么加回来?

【问题讨论】:

    标签: wpf silverlight wpfdatagrid


    【解决方案1】:

    我认为您将不得不重新模板化 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>
    

    【讨论】:

    • 为什么这么复杂?有简单的方法吗?
    • @user496949:恐怕是这样。排序箭头属于模板(连同标题等),所以要找回它们,我们必须重新模板化整个东西。无论如何,我从来没有见过解决这个问题的方法。
    • 是的,这是唯一的方法。
    • 嗨@FredrikHedblad,无论如何都要以编程方式触发箭头吗?您可以在这里stackoverflow.com/questions/50331237/… 提出问题
    【解决方案2】:

    这是一篇博客文章,它很好地分解了 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 是故意设置样式的,以便在更改背景颜色时隐藏排序指示器。有时我只是不明白微软是如何维持业务的。为什么你要设计如此丑陋的控件,然后在开发人员试图修复它时破坏其他关键功能。

    我们必须重新模板化 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。 Grid 控制标题的布局,左侧是 Content 区域,右侧是 Sort Indicator。请注意,排序指示符是使用路径定义的。这两个矩形为列标题生成可见的左右边缘。 Thumbs 必须定义并允许用户调整列的大小。稍后我们将定义 ThumbStyle。注意边界的名称。我们需要这个,所以我们可以在步骤 3 中使用触发器来改变它。在结束 Style 标记之前添加它。

    <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 步 - 添加触发器以在鼠标移到列标题上时更改边框颜色。在 Grid 结束标记之后添加以下触发器。

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

    ** **更新:样式条目组合在一起 **

    <FontFamily x:Key="Corp_FontFamily">Segoe UI</FontFamily>
    <clr:Double x:Key="Corp_FontSize">13</clr:Double>
    <Style TargetType="{x:Type Control}" x:Key="baseStyle">
        <Setter Property="FontFamily" Value="{StaticResource Corp_FontFamily}" />
        <Setter Property="FontSize" Value="{StaticResource Corp_FontSize}" />
    </Style>
    
    <Color x:Key="CorpBlue_T1S1" A="255" R="172" G="180" B="196"/>
    <SolidColorBrush x:Key="Brush_CorpBlue_T1S1" Color="{StaticResource CorpBlue_T1S1}"/>
    
    <Color x:Key="CLR_Green" A="255" R="220" G="239" B="202"/>
    <SolidColorBrush x:Key="YourCompany_HeaderColumnDefaultBackground" Color="{StaticResource CLR_Green}"/>
    
    <Style TargetType="DataGridColumnHeader" x:Key="DG_Hdr_Base" BasedOn="{StaticResource baseStyle}">
        <Setter Property="SnapsToDevicePixels" Value="True"/>
        <Setter Property="MinWidth" Value="0"/>
        <Setter Property="MinHeight" Value="0"/>
        <Setter Property="Background" Value="{StaticResource YourCompany_HeaderColumnDefaultBackground}"/>
        <Setter Property="Cursor" Value="Hand"/>
        <Setter Property="Padding" Value="5"/>
        <Setter Property="BorderThickness" Value="0 0 1 0"/>
        <Setter Property="BorderBrush" Value="DarkGray"/>
        <Setter Property="HorizontalContentAlignment" Value="Center" />
        <Setter Property="TextBlock.TextAlignment" Value="Center" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="DataGridColumnHeader">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="Auto"/>
                        </Grid.ColumnDefinitions>
                        <Border x:Name="BackgroundBorder" BorderThickness="0,0,0,2"
                                Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                Grid.ColumnSpan="2"/>
                        <ContentPresenter Margin="5" VerticalAlignment="Center" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
                        <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="DarkGray" HorizontalAlignment="Right" Grid.ColumnSpan="2"/>
                        <Rectangle Width="1" Margin="0,0,1,0" Fill="DarkGray" 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.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="BackgroundBorder" Property="Background" Value="{StaticResource Brush_CorpBlue_T1S1}"/>
                            <Setter TargetName="BackgroundBorder" Property="BorderBrush" Value="{StaticResource ControlHighlightBorderBrush}"/>
                        </Trigger>
                        <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>
                        <Trigger Property="DisplayIndex" Value="0">
                            <Setter TargetName="PART_LeftHeaderGripper" Property="Visibility" Value="Collapsed"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    【讨论】:

    • 很好的例子。建议添加最终显示,以说明如何为经验不足的人一起定义所有元素。
    • 感谢@str8ball 的反馈。添加了样式元素的合并。
    • 表格的标题文本是否可以居中对齐,因为它在上面的例子中是左对齐的。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-06
      • 2011-07-18
      • 2011-05-27
      • 2013-01-02
      • 2012-09-24
      • 2013-07-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多