如何更改ListView列重新排序分隔符指示符的样式?

时间:2015-01-10 14:47:54

标签: wpf listview separator

如何更改ListView列重新排序分隔符指示符的样式? (当您尝试重新排序列时出现的蓝线,如下图所示)

enter image description here

以下奇怪的是只改变高度:

<ListView>
    <ListView.Resources>
        <Style TargetType="{x:Type Separator}">
            <Setter Property="Height"
                    Value="5" />
            <Setter Property="Foreground"
                    Value="Red" />
            <Setter Property="Background"
                    Value="Red" />
        </Style>
    </ListView.Resources>
    <ListView.View>
        <GridView >
            <GridViewColumn Header="First Name"
                            Width="100" />
            <GridViewColumn Header="Last Name"
                            Width="100" />
        </GridView>
    </ListView.View>
</ListView>

我尝试过很多东西,包括

  • 设置SeparatorStyleKey(工具栏,MenuItem,StatusBar)
  • 覆盖SystemColors

但没有运气。

2 个答案:

答案 0 :(得分:0)

嗯,这有点复杂......为此,你必须为Thumb创建一个样式。

例如(使用Blend提取的默认样式):

<Style x:Key="GridViewColumnHeaderGripper" TargetType="{x:Type Thumb}">
        <Setter Property="Canvas.Right" Value="-9"/>
        <Setter Property="Width" Value="18"/>
        <Setter Property="Height" Value="{Binding ActualHeight, RelativeSource={RelativeSource TemplatedParent}}"/>
        <Setter Property="Padding" Value="0"/>
        <Setter Property="Background" Value="{StaticResource GridViewColumnHeaderBorderBackground}"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Thumb}">
                    <Border Background="Transparent" Padding="{TemplateBinding Padding}">
                        <Rectangle Fill="{TemplateBinding Background}" HorizontalAlignment="Center" Width="1"/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

然后你必须创建一个GridViewColumnHeaderStyle。 例如(使用Blend提取的默认样式。为了简单起见,我删除了一些触发器):

        <Style x:Key="GridViewColumnHeaderStyle1" TargetType="{x:Type GridViewColumnHeader}">
        <Setter Property="HorizontalContentAlignment" Value="Center"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>
        <Setter Property="Background" Value="{StaticResource GridViewColumnHeaderBackground}"/>
        <Setter Property="BorderBrush" Value="{StaticResource GridViewColumnHeaderBorderBackground}"/>
        <Setter Property="BorderThickness" Value="0"/>
        <Setter Property="Padding" Value="2,0,2,0"/>
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type GridViewColumnHeader}">
                    <Grid SnapsToDevicePixels="true">
                        <Border x:Name="HeaderBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0,1,0,1" Background="{TemplateBinding Background}">
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition MaxHeight="7"/>
                                    <RowDefinition/>
                                </Grid.RowDefinitions>
                                <Rectangle x:Name="UpperHighlight" Fill="#FFE3F7FF" Visibility="Collapsed"/>
                                <Border Padding="{TemplateBinding Padding}" Grid.RowSpan="2">
                                    <ContentPresenter x:Name="HeaderContent" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="0,0,0,1" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                                </Border>
                            </Grid>
                        </Border>
                        <Border x:Name="HeaderHoverBorder" BorderThickness="1,0,1,1" Margin="1,1,0,0"/>
                        <Border x:Name="HeaderPressBorder" BorderThickness="1,1,1,0" Margin="1,0,0,1"/>
                        <Canvas>
                            <Thumb x:Name="PART_HeaderGripper" Style="{StaticResource GridViewColumnHeaderGripper}"/>
                        </Canvas>
                    </Grid>
            </ControlTemplate>
            </Setter.Value>
        </Setter>

当然,在这些样式中,您可以更改任何您想要的内容。可能你必须这样做,因为这些只是我之前想到的默认样式。

答案 1 :(得分:0)

事实证明,模板实际上是硬编码的。请参阅GridViewHeaderRowPresenter的源代码。 AddIndicator()如下所示

// Create the indicator for column re-ordering
    private void AddIndicator()
    {
        Separator indicator = new Separator();
        indicator.Visibility = Visibility.Hidden;

        // Indicator style:
        //
        // <Setter Property="Margin" Value="0" />
        // <Setter Property="Width" Value="2" />
        // <Setter Property="Template">
        //   <Setter.Value>
        //     <ControlTemplate TargetType="{x:Type Separator}">
        //        <Border Background="#FF000080"/>
        //     </ControlTemplate>
        //   </Setter.Value>
        // </Setter>

        indicator.Margin = new Thickness(0);
        indicator.Width = 2.0;

        FrameworkElementFactory border = new FrameworkElementFactory(typeof(Border));
        border.SetValue(Border.BackgroundProperty, new SolidColorBrush(Color.FromUInt32(0xFF000080)));

        ControlTemplate template = new ControlTemplate(typeof(Separator));
        template.VisualTree = border;
        template.Seal();

        indicator.Template = template;

        InternalChildren.AddInternal(indicator);
        _indicator = indicator;
    }

这是我使用的解决方法(可以很容易地变成附加属性)

void ListView_Loaded(object sender, RoutedEventArgs e)
    {
        var listView = sender as ListView;
        if (listView != null)
        {
            var gvhrp = FindFirstVisual<GridViewHeaderRowPresenter>(listView);
            if (gvhrp != null)
            {
                var separator = FindFirstVisual<Separator>(gvhrp);
                if (separator != null)
                {
                    separator.IsVisibleChanged += delegate
                    {
                        var border = FindFirstVisual<Border>(separator);
                        if (border != null)
                        {
                            border.Background = Brushes.Red;
                        }
                    };
                }
            }
        }
    }

    T FindFirstVisual<T>(DependencyObject depObj) where T : DependencyObject
    {
        if (depObj != null)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                if (child != null && child is T)
                {
                    return (T)child;
                }

                var result = FindFirstVisual<T>(child);
                if (result != null)
                {
                    return result;
                }
            }
        }

        return null;
    }