Of late, I have been working with Net Advantage for WPF by Infragistics, but today, we didn’t really need the full functionality of a DataGrid
and needed a rather lighter weight component (basically simply sorting list, no paging, no grouping…just a list), so I turned my attention back to the inbuilt WPF controls (there is a WPF Datagrid
that was released out of bands within the WPF Toolkit, should you want a free WPF grid), where I needed a ListView
.
Now I like the ListView
but I have always stuggled a little bit with getting it to look how I wanted visually, one area where I seem to always have issues is changed the header (where the column names are shown).
I had initially looked into doing this with Blend following the instructions here which although very accurate, result in about 300 lines of code, most of which I didn’t want to change. Basically, all I was after was a new Colour
in the header section.
Now if you use Blend and are happy with what it produces that’s all cool, I am not against that. It’s just that I feel the hand written approach is a little nicer on the XAML content. You see what happens when you work with Expression Blend in design mode, and start editing control templates, you will get the entire set of XAML to make the control from scratch, but you may only actually need to style/template 1 particular control.
In order to restyle the ListView
header, I had to do the following:
1: <LinearGradientBrush x:Key="BlueRinseBrush"
2: EndPoint="0.5,1" StartPoint="0.5,0">
3: <GradientStop Color="#FF223B84" Offset="1"/>
4: <GradientStop Color="#FF57A0F4" Offset="0.5"/>
5: <GradientStop Color="#FF4B94EC" Offset="0.5"/>
6: </LinearGradientBrush>
7:
8:
9: <Style x:Key="GridViewColumnHeaderGripper"
10: TargetType="Thumb">
11: <Setter Property="Width" Value="18"/>
12: <Setter Property="Background" Value="White"/>
13: <Setter Property="Template">
14: <Setter.Value>
15: <ControlTemplate TargetType="{x:Type Thumb}">
16: <Border Padding="{TemplateBinding Padding}"
17: Background="Transparent">
18: <Rectangle HorizontalAlignment="Center"
19: Width="3"
20: Fill="{TemplateBinding Background}"/>
21: </Border>
22: </ControlTemplate>
23: </Setter.Value>
24: </Setter>
25: </Style>
26:
27: <Style x:Key="GridViewColumnHeaderStyle"
28: TargetType="GridViewColumnHeader">
29: <Setter Property="HorizontalContentAlignment"
30: Value="Center"/>
31: <Setter Property="VerticalContentAlignment"
32: Value="Center"/>
33: <Setter Property="Background"
34: Value="{StaticResource BlueRinseBrush}"/>
35: <Setter Property="Foreground"
36: Value="{DynamicResource
37: {x:Static SystemColors.ControlTextBrushKey}}"/>
38: <Setter Property="Template">
39: <Setter.Value>
40: <ControlTemplate
41: TargetType="GridViewColumnHeader">
42: <Grid>
43: <Border Name="HeaderBorder"
44: BorderThickness="0"
45: BorderBrush="{StaticResource BlueRinseBrush}"
46: Background="{StaticResource BlueRinseBrush}"
47: Padding="2,0,2,0">
48: <ContentPresenter Name="HeaderContent"
49: TextElement.Foreground="White"
50: Margin="0,0,0,1"
51: VerticalAlignment="{TemplateBinding
52: VerticalContentAlignment}"
53: HorizontalAlignment="{TemplateBinding
54: HorizontalContentAlignment}"
55: RecognizesAccessKey="True"
56: SnapsToDevicePixels=
57: "{TemplateBinding SnapsToDevicePixels}"/>
58: </Border>
59: <Thumb x:Name="PART_HeaderGripper"
60: HorizontalAlignment="Right"
61: Margin="0,0,-9,0"
62: Style="{StaticResource
63: GridViewColumnHeaderGripper}"/>
64: </Grid>
65: <ControlTemplate.Triggers>
66: <Trigger Property="IsMouseOver" Value="true">
67: <Setter TargetName="HeaderBorder"
68: Property="Background" Value="Yellow"/>
69: <Setter TargetName="HeaderContent"
70: Property="TextElement.Foreground"
71: Value="Black"/>
72: </Trigger>
73: </ControlTemplate.Triggers>
74: </ControlTemplate>
75: </Setter.Value>
76: </Setter>
77: </Style>
Now the important part here is the approach that I took….which I believe is the key to working successfully with WPF. Basically, I would recommend you should always consult the existing control templates (the default look and feel, basically) which you can find here and only style the parts you need to change.
Anyway, the results of the code above give me what I was after, a custom header area:
Here is a small demo project.