Reputation: 1134
How do you change the style of the ListView column reorder separator indicator? (The blue line that appears when you try to reorder a column, pictured below)
The following oddly only changes the height :
<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>
I've tried a bunch of things, including
but no luck.
Upvotes: 2
Views: 801
Reputation: 1134
So it turns out the template is actually hard coded. See the source code for GridViewHeaderRowPresenter. AddIndicator() presented below
// 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;
}
here is the workaround I used (which can easily be turned into an attached property)
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;
}
Upvotes: 1
Reputation: 282
Well, It is a little bit complicated... In order to that you have to create a style for the Thumb.
For example (the extracted default style using 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>
Then you have to create a GridViewColumnHeaderStyle. For example (the extracted default style using Blend. I've deleted some triggers for the sake of simplicity):
<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>
Of course, in these styles, you can change anything you want. Probably you have to because these are just the default styles as I mentined before.
Upvotes: 0