I am attempting to create a WPF DataGrid that has alternating background colors. I am currently using DataGridTemplateColumn columns and setting the CellStyle background color but am not fully satisfied with this result:
<DataGridTemplateColumn.CellStyle>
<Style TargetType="DataGridCell">
<Style.Triggers>
<Trigger Property="IsSelected" Value="False">
<Setter Property="Background" Value="#FFF7F7F7" />
</Trigger>
</Style.Triggers>
</Style>
</DataGridTemplateColumn.CellStyle>
I am modeling my DataGrid off of an existing WinForms project and am attempting to duplicate its look. I am facing two problems:
The different column backgrounds are attached to the cells and are not properties of grid itself. Thus unused rows do not show these backgrounds. I would like even an empty grid to show the columns and backgrounds.
The column background should extend under the transparent Expander header. I believe that if (1) is satisfied, this would work as well.
Can these goals be achieved with the DataGrid directly? If not, what workarounds might solve the problem; perhaps somehow drawing the column backgrounds directly on the DataGrids panel (DataGridRowsPresenter) and supporting column resize?
Any ideas? Thanks!
NOTE: This question is similar and unanswered: WPF Datagrid Template column edit event and alternating column color
Update:
This update is based on the proposed answer by @LeslieDavies which gets me most of the way there. I have two issues with this solution:
I'm not able to star size the DataGrid columns. If I attempt to star size, the columns grow continuously without bound.
If I remove the
DataGrid.GroupStyle
from the XAML, the resizing no longer works correctly. The Rectangles grow correctly, but when shrinking the column the Rectangle shrinks but the Grid columns do not shrink properly.
XAML:
<Window x:Class="GridColumnColors.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" Background="Black">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Rectangle Name="Rect0" Grid.Column="0" HorizontalAlignment="Left" Margin="-1,0,0,0" Fill="#FFCACACA" />
<Rectangle Name="Rect1" Grid.Column="1" HorizontalAlignment="Left" Margin="-1,0,0,0" Fill="White"/>
<Rectangle Name="Rect2" Grid.Column="2" HorizontalAlignment="Left" Margin="-1,0,0,0" Fill="#FFCACACA"/>
<DataGrid Name="DataGridStudents" AutoGenerateColumns="False" Visibility="Visible" Grid.ColumnSpan="4" ItemsSource="{Binding StudentsCollectionView}"
SelectionMode="Extended" GridLinesVisibility="None" RowHeaderWidth="0" RowBackground="Transparent"
CanUserResizeRows="False" IsReadOnly="True" Background="Transparent" LayoutUpdated="Students_LayoutUpdated">
<DataGrid.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander Header="{Binding}">
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</DataGrid.GroupStyle>
<DataGrid.Columns>
<DataGridTextColumn Header="First Name" MinWidth="100" Binding="{Binding FirstName}"/>
<DataGridTextColumn Header="Last Name" MinWidth="100" Binding="{Binding LastName}"/>
<DataGridTextColumn Header="Age" MinWidth="100" Binding="{Binding Age}"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
Code Behind:
private void Students_LayoutUpdated(object sender, EventArgs e)
{
Rect0.Width = DataGridStudents.Columns[0].ActualWidth+3;
Rect1.Width = DataGridStudents.Columns[1].ActualWidth+0;
Rect2.Width = DataGridStudents.Columns[2].ActualWidth+1;
}