Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF datagrid column heading span more than once column

Tags:

wpf

datagrid

In a WPF datagrid is it possible to group column headings?

What I'm after is

| Column 1 | Column 2 | Column 3|
| a  b  c  | a  b  c  | a  b  c |
| z  x  y  | z  x  y  | z  x  y |

I've searched around and can't see an obvious way of doing this. I could use a templated column and then mimick the extra cells within the each template but that wouldn't work well for ordering etc.

I suppose all I'm saying it that I'm looking for is how people have managed to span column headings across multiple coluns.

Any help or ideas would be greatly appreciated.

like image 296
Sam Brinsted Avatar asked Dec 29 '22 20:12

Sam Brinsted


1 Answers

This is an old thread, but I thought I should share how I did it.

In my application, I want to display three columns of date entries, under a single column header, "Maintenance Fee Dates." I created a single column, with two DataTemplates, one for display and one for editing:

<DataGrid.Resources>
  <DataTemplate x:Key="cellTemplate">
     <Grid>
        <Grid.ColumnDefinitions>
           <ColumnDefinition Width="100" />
           <ColumnDefinition Width="100" />
           <ColumnDefinition Width="100" />
        </Grid.ColumnDefinitions>
        <TextBlock x:Name="tbDate1"
                    Text="{Binding Path=Date1}"
                    Grid.Column="0" />
        <TextBlock x:Name="tbDate2"
                    Text="{Binding Path=Date2}"
                    Grid.Column="1" />
        <TextBlock x:Name="tbDate3"
                    Text="{Binding Path=Date3}"
                    Grid.Column="2" />
     </Grid>
  </DataTemplate>
  <DataTemplate x:Key="cellEditingTemplate">
     <Grid>
        <Grid.ColumnDefinitions>
           <ColumnDefinition Width="100" />
           <ColumnDefinition Width="100" />
           <ColumnDefinition Width="100" />
        </Grid.ColumnDefinitions>
        <DatePicker Grid.Column="0"
                    Margin="0"
                    Name="dpDate1"
                    Width="100"
                    SelectedDate="{Binding Path=Date1}" />
        <DatePicker Grid.Column="1"
                    Margin="0"
                    Name="dpDate2"
                    Width="100"
                    SelectedDate="{Binding Path=Date2}" />
        <DatePicker Grid.Column="2"
                    Margin="0"
                    Name="dpDate3"
                    Width="100"
                    SelectedDate="{Binding Path=Date3}" />
     </Grid>
  </DataTemplate>

Then I define the column as a DataGridTemplateColumn, pointing at the DataTemplates above:

<DataGrid.Columns>
....
   <DataGridTemplateColumn CellTemplate="{StaticResource cellTemplate}"
                           Header="Maintenance Fee Dates"
                           CellEditingTemplate="{StaticResource cellEditingTemplate}" />
....
</DataGrid.Columns>

Since the DataTemplate is laid out with a Grid that has three fixed-length columns, I get three nice columns of dates (or DatePickers when editing) under the single column header.

Horizontal Gridlines can be handled by the Grid. To have vertical Gridlines between the three columns, just put the middle column's control in a Border control. Set the Border control to the same width as the Grid column, display only its right and left borders, and set its BorderBrush to match the color of the DataGrid's Gridlines:

  <DataTemplate x:Key="cellTemplate">
     <Grid>
        <Grid.ColumnDefinitions>
           <ColumnDefinition Width="100" />
           <ColumnDefinition Width="100" />
           <ColumnDefinition Width="100" />
        </Grid.ColumnDefinitions>
        <TextBlock x:Name="tbDate1"
                    Text="{Binding Path=Date1}"
                    Grid.Column="0" />
        <Border BorderThickness="1,0,1,0"
                BorderBrush="DarkGray"
                Width="100">
           <Border.Child>
              <TextBlock x:Name="tbDate2"
                          Text="{Binding Path=Date2}"
                          Grid.Column="1" />
           </Border.Child>
        </Border>
        <TextBlock x:Name="tbDate3"
                    Text="{Binding Path=Date3}"
                    Grid.Column="2" />
     </Grid>
  </DataTemplate>
like image 77
D'Hag Avatar answered Jan 20 '23 02:01

D'Hag