OK, I have searched for pretty long time for solution of this problem. I am developing simple printing system for WPF DataGrids and have managed to print tables with uniform cell placement using DataTable and setting it as DataGrid's ItemSource.
However, I needed some rows to contain only one cell (you can think of it like "row group header" inside the table).
So, since I haven't found anything about DataTable's cells spanning multiple columns (if this can be made, it would be a great thing to know how), I figured I would have to add rows to DataGrid manually, and solve it something like this:
The second point is where I have the problem (if it's right, that is). I need to add row to a DataGrid that uses simple array of strings as cell data (index in array should mach the cell index). Is there an easy way to do something like that?
So after some more fiddling with all this, I have reached a very nice solution.
The best and easiest thing to do is to apply a data template to particular rows after the DataGrid is loaded. So, I stuck to original idea with DataTables and remembered the indices that needed to have their template changed. I just took the DataGridRows from these indices and applied the template that had custom made ItemsPanelTemplate that spans multiple columns.
EDIT: On Daniel's request, I'm including some code.
First thing we need is a template for spanning row:
<ControlTemplate TargetType='{x:Type DataGridRow}'
xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
<Border>
<DataGridCellsPresenter Foreground='Black'>
<DataGridCellsPresenter.ItemsPanel>
<ItemsPanelTemplate>
<local:DataGridSpannedCellPanel />
</ItemsPanelTemplate>
</DataGridCellsPresenter.ItemsPanel>
</DataGridCellsPresenter>
</Border>
</ControlTemplate>
NOTE: local:DataGridSpannedCellPanel is a custom DataGridCellsPanel with overridden ArrangeOverride method that makes first cell span entire size.
You can make a string in code-behind and load your template from it, for example. The next thing is creating your grid and initializing some of the rows with this new template:
var newGrid = MakeNewDataGrid();
newGrid.ItemsSource = myTable.AsDataView();
var template = XamlReader.Parse(HeaderRowTemplate) as ControlTemplate;
foreach (int index in myHeaderIndices)
{
var container = newGrid.ItemContainerGenerator.ContainerFromIndex(index);
var row = container as DataGridRow;
if (row != null)
{
row.Template = template;
}
}
Also note, rows in your table need to be made as follows:
if (bindableQuote.IsGroup())
{
table.Rows.Add("Header");
}
else
{
table.Rows.Add(rowData.ToArray());
}
That's about it, the only thing left is to figure out how to implement DataGridSpannedCellPanel.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With