Introduction
While I am creating my custom applications, usually I need to show my data well formed, and want to merge cells and rows, and create a multi-level column header. I may use the builtin WPF controls like DataGrid
or GridView
but sometimes they are not helpful especially in the printing controls. In StackOverflow and on CodeProject, I searched for many days, but I couldn't find helpful things. In this tip, I am trying to solve this problem.
Using the Code
The XTable
library contains the following controls:
XTableCell
XTableColumn
XTableRow
XTable
Firstly, the XTable
is used as any WPF control:
<XTable x:Name="table" />
You can customize the XTable
with the provided properties:
<XTable x:Name="table"
RowHeight="30"
VerticalAlignment="Top"
MaxWidth="800"
BorderBrush="Black"
LinesBrush="Black"
HeaderHeight="35"
Margin="50"/>
Secondly, you should define the Columns:
<XTable x:Name="table"
RowHeight="30"
VerticalAlignment="Top"
MaxWidth="800"
BorderBrush="Black"
LinesBrush="Black"
HeaderHeight="35"
Margin="50">
<XTable.Columns>
<XTableColumn Header="Manufacture"
Binding="{Binding Manufacture,
UpdateSourceTrigger=PropertyChanged}" IsGrouped="True" />
</XTable.Columns>
</XTable>
and you can play with Columns Definitions which looks like:
<XTable x:Name="table" RowHeight="30"
VerticalAlignment="Top"
MaxWidth="800"
BorderThickness="1 1 1 0"
BorderBrush="Black"
LinesBrush="Black" HeaderHeight="35"
Margin="50">
<XTable.HeaderCellStyle>
<Style TargetType="{x:Type XTableCell}">
<Setter Property="Background" Value="#FFF0EAEA" />
<Setter Property="FontFamily" Value="Tohama" />
<Setter Property="FontWeight" Value="Bold" />
</Style>
</XTable.HeaderCellStyle>
<XTable.Columns>
<XTableColumn Header="Manufacture"
Binding="{Binding Manufacture,
UpdateSourceTrigger=PropertyChanged}" IsGrouped="True" />
<XTableColumn Header="Name"
Binding="{Binding Name,UpdateSourceTrigger=PropertyChanged}" IsGrouped="True" />
<XTableColumn Header="RAM"
Binding="{Binding RAM,UpdateSourceTrigger=PropertyChanged, StringFormat={}{0:N2}}"
IsGrouped="True" IsTransitive="True">
<XTableColumn.ContentTemplate>
<DataTemplate>
<TextBlock Text="{Binding .,StringFormat={}{0} MB}" />
</DataTemplate>
</XTableColumn.ContentTemplate>
</XTableColumn>
<XTableColumn Header="CPU"
Binding="{Binding CPU,UpdateSourceTrigger=PropertyChanged}" />
<XTableColumn Header="Price"
Binding="{Binding Price,UpdateSourceTrigger=PropertyChanged}">
<XTableColumn.CellStyle>
<Style TargetType="{x:Type XTableCell}">
<Setter Property="Background" Value="LightYellow" />
<Setter Property="FontFamily" Value="Segoe UI Light" />
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding .,StringFormat={}{0:N2} DZ}" />
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</XTableColumn.CellStyle>
</XTableColumn>
</XTable.Columns>
</XTable>
You ask about two properties of `XTableColumn
`; `IsGrouping
` and `IsTransitive
` - I will answer your question:
IsGrouping
: allows the cell merging in this column definition IsTransitive
: indicates if the column merging refers to the previous cell or no, for example in our model:
public class Laptop
{
public string Manufacture { get; set; }
public string Name { get; set; }
public double RAM { get; set; }
public string CPU { get; set; }
public double Price { get; set; }
}
and by using the XTable
defined above, I got this result:
Suppose the laptop Dell, Inspiron 1525 and Dell, Studio 1535 have the same CPU and different RAM and we mark the CPU column IsGrouping True
and IsTransitive False
, do not forget the two laptops have the same manufacturer, so we can have cell merging in this case because the RAMs are distinct in others hence if IsTranstive
turned to True
, we can see the cell merging in the CPU cell.
IsTransitive
takes care of the parent grouping cell, in some cases two rows having the same value in a cell but they are not in the same row, and they are neighbors.
The XTable
has `ItemsSource
` property. You can bind it or set it in code behind:
table.ItemsSource = DataProvider.GetLaptops();
You can find the Open Source project at Github: