Printing in WPF DataGrid (SfDataGrid)

SfDataGrid provides support to print the data displayed in the DataGrid using SfDataGrid.Print method. It also provides support to display print preview window by calling SfDataGrid.ShowPrintPreview method.

dataGrid.Print();

SfDataGrid provides option to display print preview to review and customize the document in desired format before printing. Print preview window can be opened by calling SfDataGrid.ShowPrintPreview method.

dataGrid.ShowPrintPreview();

Print preview window for WPF DataGrid before printing

SfDataGrid provides various options to customize print preview settings using SfDataGrid.PrintSettings property of type PrintSettings.

dataGrid.PrintSettings = new PrintSettings();
dataGrid.PrintSettings.AllowRepeatHeaders = false;            
dataGrid.Print();

Print

Print preview window has Print and Quick Print Buttons which needs to be clicked to print the SfDataGrid.

Print and Quick Print buttons in print preview window of WPF DataGrid

  1. Clicking the Print button opens the System print dialog where user can select the printer and set the number of copies to be printed.

    Shows the system print dialog for printing WPF DataGrid

  2. Clicking the Quick Print button, directly print the pages using default printer without opening the print dialog.

Scaling

SfDataGrid provides support to scale rows or columns or both while printing to fit on one page. Scaling options can be changed by setting PrintSettings.PrintScaleOption property.

dataGrid.PrintSettings = new PrintSettings();
dataGrid.PrintSettings.PrintScaleOption = PrintScaleOptions.FitAllColumnsonOnePage;
dataGrid.ShowPrintPreview();

Scaling options can be changed in print preview at runtime by selecting from scaling options drop-down in print preview.

Print scaling options in print preview window of WPF DataGrid

Column Header on each page

Column headers can be printed on each page by enabling PrintSettings.AllowRepeatHeaders property while printing.

dataGrid.PrintSettings = new PrintSettings();
dataGrid.PrintSettings.AllowRepeatHeaders = true;
dataGrid.Print();

Changing Flow Direction while printing

You can change the text direction in print page by using PrintSettings.PrintFlowDirection property.

dataGrid.PrintSettings = new PrintSettings();
dataGrid.PrintSettings.PrintFlowDirection = FlowDirection.RightToLeft;
dataGrid.Print();

SfDataGrid provides support to print the StackedHeaders by setting the PrintSettings.CanPrintStackedHeaders as ‘true’.

this.sfDataGrid.PrintSettings.CanPrintStackedHeaders = true;

Shows stacked headers printing in WPF DataGrid

Page Settings

SfDataGrid provides various options to customize page settings using SfDataGrid.PrintSettings property of type PrintSettings.

Orientation

SfDataGrid provides support to switch between Portrait (more rows but fewer columns) and Landscape (more columns but fewer rows) orientation while printing. Orientation can be changed by setting PrintSettings.PrintPageOrientation Property.

dataGrid.PrintSettings = new PrintSettings();
dataGrid.PrintSettings.PrintPageOrientation = PrintOrientation.Landscape;
dataGrid.ShowPrintPreview();

Print orientation can be changed in print preview at runtime by selecting from orientation drop-down in print preview.

Page orientation options in print preview window for WPF DataGrid

Page size

SfDataGrid provides support to change the page size. Page size can be changed by setting PrintSettings.PrintPageWidth and PrintSettings.PrintPageHeight properties.

dataGrid.PrintSettings = new PrintSettings();
dataGrid.PrintSettings.PrintPageHeight = 800;            
dataGrid.PrintSettings.PrintPageWidth = 800;
dataGrid.Print();

Page size can be changed in print preview also by selecting from page-size drop-down which displays pre-defined page sizes. You can also manually enter custom page width and height in the editors below page-size drop-down and press OK to apply the custom width and height for the page.

Page size options in print preview window for WPF DataGrid

Page margin

SfDataGrid provides support to change the page margins to adjust content in printed page. Page margin can be changed by setting PrintSettings.PrintPageMargin property.

dataGrid.PrintSettings = new PrintSettings();
dataGrid.PrintSettings.PrintPageMargin = new Thickness(5);
dataGrid.Print();

Page margin can be changed in print preview also by selecting from pre-defined page margin from margin drop-down. You can manually enter custom margins in the editors below margin drop-down and press OK to apply the custom margin.

Page margin options in print preview window for WPF DataGrid

SfDataGrid provides a way to display additional content at the top (Header) or bottom (Footer) of the page while printing. This can be achieved by setting PrintPageHeaderHeight , PrintPageHeaderTemplate , PrintPageFooterHeight PrintPageFooterTemplate properties in PrintSettings.

Steps to add page header while printing,

  1. Create DataTemplate in Application.Resources.
<Application.Resources>
    <DataTemplate x:Key="PageHeaderTempalte">
        <Grid Background="Gray">
            <TextBlock Text="Syncfusion" 
                       FontSize="18" 
                       FontWeight="Bold" 
                       Foreground="White" 
                       HorizontalAlignment="Center"/>
        </Grid>
    </DataTemplate>
</Application.Resources>

2.Set the above defined DataTemplate to PrintSettings.PrintPageHeaderTemplate and assign value for PrintSettings.PrintPageHeaderHeight property also.

dataGrid.PrintSettings = new PrintSettings();
dataGrid.PrintSettings.PrintPageHeaderHeight = 30;
dataGrid.PrintSettings.PrintPageHeaderTemplate = Application.Current.Resources["PageHeaderTempalte"] as DataTemplate;
dataGrid.ShowPrintPreview();

3.Now run the application and you can see page header in all the pages. In the same way, you can set PrintSettings.PrintPageFooterTemplate also.

Customized HeaderTemplate and HeaderHeight in print preview window for WPF DataGrid

NOTE

PrintManagerBase is the DataContext for PrintPageControl, where the header and footer templates are loaded.

Printing Current Date time and Page number

You can print current Date and Time at each page by setting the PrintPageFooterHeight PrintPageFooterTemplate properties in PrintSettings.

You can get the page number from PrintPageControl.

<Application.Resources>
    <DataTemplate x:Key="PageFooterTempalte">
        <Grid>
            <TextBlock HorizontalAlignment="Center" 
                       FontSize="20" 
                       Text="{Binding Source={x:Static system:DateTime.Now}}"/>
            <TextBlock Margin="0,0,10,0"
                       HorizontalAlignment="Right"
                       VerticalAlignment="Center" FontSize="20">
                <TextBlock.Text>
                    <Binding Path="PageIndex"
                             RelativeSource="{RelativeSource Mode=FindAncestor,
                                                              AncestorType={x:Type syncfusion:PrintPageControl}}"
                             StringFormat="Page : {0}" />
                </TextBlock.Text>
            </TextBlock>
        </Grid>
    </DataTemplate>
</Application.Resources>
dataGrid.PrintSettings = new PrintSettings();
dataGrid.PrintSettings.PrintPageFooterHeight = 30;
dataGrid.PrintSettings.PrintPageFooterTemplate = Application.Current.Resources["PageFooterTempalte"] as DataTemplate;
dataGrid.ShowPrintPreview();

Customized FooterTemplate and FooterHeight in print preview window for WPF DataGrid

Different modes of printing for better performance

Printing using drawing for better performance

When you require better performance and don’t want appearance settings (Background and Foreground) to be exported while printing then you can use this printing option by setting PrintSettings.AllowPrintByDrawing property to true.

NOTE

This is default print mode. For appearance customization of rows and cells while printing, refer printing customization section.

Printing using UIElement Rendering

When you want to print the SfDataGrid with same appearance settings as in the display (Background and Foreground) or with custom appearance by writing styles, then you can enable this print option by setting PrintSettings.AllowPrintByDrawing property to false.

You can print SfDataGrid as it displayed in View by setting PrintSettings.AllowPrintStyles to true.

dataGrid.PrintSettings = new PrintSettings();
dataGrid.PrintSettings.AllowPrintByDrawing = false;
dataGrid.PrintSettings.AllowPrintStyles = true;
dataGrid.ShowPrintPreview();

GridHeaderCellControl style customized and the same style will be exported while printing by setting PrintSettings.AllowPrintStyles to true.

<Application.Resources>
     <Style TargetType="syncfusion:GridHeaderCellControl">
         <Setter Property="Background" Value="LightPink"/>            
     </Style>
</Application.Resources>

Shows same style as in view for WPF DataGrid using AllowPrintStyles API while printing

Applying custom style

Custom styles can be applied while printing by setting PrintSettings.AllowPrintStyles to false and writing style for below controls based on your requirement.

Appearance to be customized TargetType of Style
Header Cell

PrintHeaderCell

Normal Cells

PrintGridCell

Caption summary cells

PrintCaptionSummaryCell

Group summary cells

PrintGroupSummaryCell

Table summary cells

PrintTableSummaryCell

Unbound row cells

PrintUnboundRowCell

To provide custom appearance for Header cells while printing, PrintHeaderCell style is customized.

<Application.Resources>
    <Style TargetType="syncfusion:PrintHeaderCell">
         <Setter Property="Background" Value="LightSkyBlue"/>            
    </Style>
</Application.Resources>

To print SfDataGrid with custom styles, set PrintSettings.AllowPrintByDrawing and PrintSettings.AllowPrintStyles properties to false.

dataGrid.PrintSettings = new PrintSettings();
dataGrid.PrintSettings.AllowPrintByDrawing = false;
dataGrid.PrintSettings.AllowPrintStyles = false;
dataGrid.ShowPrintPreview();

WPF DataGrid displaying custom style for using AllowPrintStyles API while printing

Printing Customization

Printing operations can be customized by overriding GridPrintManager and its available methods.

Setting different Row Height

SfDataGrid allows you to set different Row height for specific rows while printing. You can achieve this by overriding the GetRowHeight method in PrintManagerBase class.

public class CustomPrintManager : GridPrintManager
{

    public CustomPrintManager(SfDataGrid grid)
        : base(grid)
    {
    }

    protected override double GetRowHeight(object record, int rowIndex, RowType type)
    {

        if (rowIndex != -1 && !(record is Group))

            if (rowIndex % 2 != 0)

                return 50.0;

        return base.GetRowHeight(record, rowIndex, type);
    }        
}
dataGrid.PrintSettings.PrintManagerBase = new CustomPrintManager(this.dataGrid);
dataGrid.ShowPrintPreview();

Customization of row height while printing in WPF DataGrid

Hiding rows while printing

You can hide specific row by using GetRowHeight method in PrintManagerBase class and setting height as 0.

Here, unbound row is excluded while printing. Likewise, you can hide any row based on record and row index.

public class CustomPrintManager : GridPrintManager
{

    public CustomPrintManager(SfDataGrid grid)
        : base(grid)
    {
    }

    protected override double GetRowHeight(object record, int rowIndex, RowType type)
    {

        if (record is GridUnBoundRow)
            return 0;

        return base.GetRowHeight(record, rowIndex, type);
    }        
}
dataGrid.PrintSettings.PrintManagerBase = new CustomPrintManager(this.dataGrid);
dataGrid.ShowPrintPreview();

Setup columns to be printed

SfDataGrid allows you to exclude the columns while printing the grid. You can change the column list by overriding the GetColumnNames method in PrintManagerBase class.

private class CustomPrintManager : GridPrintManager
{
 
    public CustomPrintManager(SfDataGrid grid)
        : base(grid)
    {
    }

    protected override List<string> GetColumnNames()
    {
        List<string> columnList = this.dataGrid.Columns.Select(x => x.MappingName).ToList();
        columnList.Remove("CustomerName");
        return columnList;
    }
}
dataGrid.PrintSettings.PrintManagerBase = new CustomPrintManager(this.dataGrid);
dataGrid.ShowPrintPreview();

Here, CustomerName column is displayed in grid. But it is excluded while printing.

Shows removal column while printing in WPF DataGrid

Customize the header text while printing

SfDataGrid allows you to change column header text while printing the grid. You can change the Column header text by overriding the GetColumnHeaderText method in GridPrintManager.

private class CustomPrintManager : GridPrintManager
{
  
    public CustomPrintManager(SfDataGrid grid)
        : base(grid)
    {
    }

    protected override string GetColumnHeaderText(string mappingName)
    {
  
        if (mappingName == "OrderID")
            return "Order ID";
            
        return base.GetColumnHeaderText(mappingName);
    }
}
dataGrid.PrintSettings.PrintManagerBase = new CustomPrintManager(this.dataGrid);
dataGrid.ShowPrintPreview();

Here, OrderID column Header text is changed as “Order ID” while printing.

customize the column header text while printing in WPF DataGrid

Styling Rows when AllowPrintByDrawing enabled

You can apply row styles based on custom condition by overriding OnRenderCell method in GridPrintManager class.

private class CustomPrintManager : GridPrintManager
{
 
    public CustomPrintManager(SfDataGrid grid)
        : base(grid)
    {
    }

    protected override void OnRenderCell(DrawingContext drawingContext, RowInfo  rowInfo, CellInfo cellInfo)
    {
 
        if (!(rowInfo.Record is RecordEntry))
        {
            base.OnRenderCell(drawingContext, rowInfo, cellInfo);
            return;
        }
        var rect = new Rect((cellInfo.CellRect).X, (cellInfo.CellRect).Y + 0.5,  (cellInfo.CellRect).Width, (cellInfo.CellRect).Height);
        
        if (((rowInfo.Record as RecordEntry).Data as OrderInfo).Country == "Germany")
            drawingContext.DrawGeometry(new SolidColorBrush(Colors.Bisque), new Pen(), new RectangleGeometry(rect));
            
        else if (((rowInfo.Record as RecordEntry).Data as OrderInfo).Country == "Mexico")
            drawingContext.DrawGeometry(new SolidColorBrush(Colors.LightSkyBlue), new Pen(), new RectangleGeometry(rect));
            
        base.OnRenderCell(drawingContext, rowInfo, cellInfo);
    }
}
dataGrid.PrintSettings.PrintManagerBase = new CustomPrintManager(this.dataGrid);
dataGrid.ShowPrintPreview();

Row styling with AllowPrintByDrawing enabled while printing in WPF DataGrid

Styling Rows when AllowPrintByDrawing disabled

You can apply row styles based on custom logic by overriding GetPrintGridCell method in GridPrintManager.

private class CustomPrintManager : GridPrintManager
{
 
    public CustomPrintManager(SfDataGrid grid)
        : base(grid)
    {
    }

    public override ContentControl GetPrintGridCell(object record, string mappingName)
    {
 
        if (!(record is OrderInfo))
            return base.GetPrintGridCell(record, mappingName);

        if ((record as OrderInfo).Country == "Germany")
            return new PrintGridCell() { Background = new SolidColorBrush(Colors.Bisque) };
            
        else if ((record as OrderInfo).Country == "Mexico")
            return new PrintGridCell() { Background = new SolidColorBrush(Colors.LightSkyBlue) };
            
        return base.GetPrintGridCell(record, mappingName);
    }
}
dataGrid.PrintSettings.PrintManagerBase = new CustomPrintManager(this.dataGrid);
dataGrid.PrintSettings.AllowPrintByDrawing = false;
dataGrid.ShowPrintPreview();

Row styling with AllowPrintByDrawing disabled while printing in WPF DataGrid

Appearance to be customized Method
Header Cell

GetPrintHeaderCell

Normal Cells

GetPrintGridCell

Caption summary cells

GetPrintCaptionSummaryCell

Group summary cells

GetPrintGroupSummaryCell

Table summary cells

GetPrintTableSummaryCell

Unbound row cells

GetPrintUnboundRowCell

Setup alternate row style when AllowPrintByDrawing enabled

SfDataGrid allows you to apply alternative row style by overriding OnRenderCell method in GridPrintManager.

private class CustomPrintManager : GridPrintManager
{

    public CustomPrintManager(SfDataGrid grid)
        : base(grid)
    {
    }

    protected override void OnRenderCell(DrawingContext drawingContext, RowInfo  rowInfo, CellInfo cellInfo)
    {
        var index = dataGrid.View.Records.IndexOfRecord(rowInfo.Record);
        var rect = new Rect((cellInfo.CellRect).X, (cellInfo.CellRect).Y + 0.5, (cellInfo.CellRect).Width, (cellInfo.CellRect).Height);
        
        if (index % 2 == 0)
            drawingContext.DrawGeometry(new SolidColorBrush(Colors.Bisque), new Pen(), new RectangleGeometry(rect));
            
        base.OnRenderCell(drawingContext, rowInfo, cellInfo);
    }
}
dataGrid.PrintSettings.PrintManagerBase = new CustomPrintManager(this.dataGrid);
dataGrid.ShowPrintPreview();

Alternate row styling with AllowPrintByDrawing enabled while printing in WPF DataGrid

Setup alternate row style when AllowPrintByDrawing disabled

SfDataGrid allows you to apply alternative row style by overriding GetPrintGridCell method in GridPrintManager.

private class CustomPrintManager : GridPrintManager
{

    public CustomPrintManager(SfDataGrid grid)
        : base(grid)
    {
    }

    public override ContentControl GetPrintGridCell(object record, string  mappingName)
    {
        var index = dataGrid.View.Records.IndexOfRecord(record);
        
        if (index % 2 == 0)
            return new PrintGridCell() { Background = new SolidColorBrush(Colors.Bisque) };
            
        return base.GetPrintGridCell(record, mappingName);
    }
}
dataGrid.PrintSettings.PrintManagerBase = new CustomPrintManager(this.dataGrid);
dataGrid.PrintSettings.AllowPrintByDrawing = false;
dataGrid.ShowPrintPreview();

Alternate row styling with AllowPrintByDrawing disabled while printing in WPF DataGrid

Styling Columns when AllowPrintByDrawing enabled

You can apply column styles based on some conditions by overriding OnRenderCell, GetFormattedText methods in GridPrintManager.

private class CustomPrintManager : GridPrintManager
{

    public CustomPrintManager(SfDataGrid grid)
        : base(grid)
    {
    }

    protected override void OnRenderCell(DrawingContext drawingContext, RowInfo  rowInfo, CellInfo cellInfo)
    {

        if (cellInfo.ColumnName == "OrderID" && rowInfo.Record != null)
        {
            var rect = new Rect((cellInfo.CellRect).X, (cellInfo.CellRect).Y + 0.5, (cellInfo.CellRect).Width, (cellInfo.CellRect).Height);
            drawingContext.DrawGeometry(new SolidColorBrush(Colors.LightGreen), new Pen(), new RectangleGeometry(rect));
        }
        
        base.OnRenderCell(drawingContext, rowInfo, cellInfo);
    }

    protected override FormattedText GetFormattedText(RowInfo rowInfo, CellInfo cellInfo, string cellValue)
    {
        var formattedText = base.GetFormattedText(rowInfo, cellInfo, cellValue);
        
        if (cellInfo.ColumnName == "OrderID" && rowInfo.Record != null)
            formattedText.SetFontStyle(FontStyles.Italic);
            
        return formattedText;
    }
}
dataGrid.PrintSettings.PrintManagerBase = new CustomPrintManager(this.dataGrid);
dataGrid.ShowPrintPreview();

Column styling with AllowPrintByDrawing enabled while printing in WPF DataGrid

Here, OrderID column Font Style and Background are changed.

Styling Columns when AllowPrintByDrawing disabled

You can apply column styles based on custom logic by overriding GetPrintGridCell method in GridPrintManager.

private class CustomPrintManager : GridPrintManager
{

    public CustomPrintManager(SfDataGrid grid)
        : base(grid)
    {
    }

    public override ContentControl GetPrintGridCell(object record, string mappingName)
    {

        if (mappingName == "OrderID")
            return new PrintGridCell() { Background = new  SolidColorBrush(Colors.LightGreen), FontStyle = FontStyles.Italic };
            
        return base.GetPrintGridCell(record, mappingName);          
    }
}
dataGrid.PrintSettings.PrintManagerBase = new CustomPrintManager(this.dataGrid);
dataGrid.PrintSettings.AllowPrintByDrawing = false;
dataGrid.ShowPrintPreview();

Column styling with AllowPrintByDrawing disabled while printing in WPF DataGrid

NOTE

GetColumnWidth , GetColumnTextWrapping, GetColumnTextAlignment and GetColumnPadding methods are also used for column customization while printing.

Printing Selected rows

Selected rows can be printed by overriding GetSourceListForPrinting method in PrintManagerClass class.

private class CustomPrintManager : GridPrintManager
{

    public CustomPrintManager(SfDataGrid grid)
        : base(grid)
    {
    }

    protected override IList GetSourceListForPrinting()
    {
        List<object> selectedRecords = new List<object>();
        var selectedRows = dataGrid.SelectionController.SelectedRows.ToList();

        foreach (var row in selectedRows)
        {

            if (row.IsAddNewRow || (row.NodeEntry != null && (!row.NodeEntry.IsRecords)))
                continue;

            if (row.IsUnBoundRow)
            {
                var _row = dataGrid.UnBoundRows.FirstOrDefault(r => r.Position == row.GridUnboundRowInfo.Position && r.ShowBelowSummary == row.GridUnboundRowInfo.ShowBelowSummary && r.RowIndex == row.GridUnboundRowInfo.RowIndex);
                selectedRecords.Add(_row);
            }

            else
                selectedRecords.Add(row.NodeEntry);
        }
        return selectedRecords;
    }
}
dataGrid.PrintSettings.PrintManagerBase = new CustomPrintManager(this.dataGrid);
dataGrid.ShowPrintPreview();

Print the selected items in WPF DataGrid

Creating custom PrintPreview window

You can create custom print preview window by adding PrintPreviewAreaControl to preview the view. PrintManagerBase will handle the printing operations and PrintPreviewAreaControl is responsible for preview.

Steps to create custom print preview window.

1.Add PrintPreviewAreaControl and required controls to print or customize the print settings.

<Grid>
    <Grid Background="#FFF7F7F7">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <Border Background="#FFDBDBDB" DataContext="{Binding ElementName=PrintPreviewArea}">
            <StackPanel Margin="10,5"
                        HorizontalAlignment="Center"
                        Orientation="Horizontal">
                    <Button Height="38"
                        Margin="10,3"
                        Command="{Binding PrintCommand}"
                        Content="Print"
                        Style="{StaticResource PrintButtonStyle}"
                        ToolTip="Print" />
                </StackPanel>
        </Border>

        <syncfusion:PrintPreviewAreaControl x:Name="PrintPreviewArea" Grid.Row="1" />

    </Grid>
</Grid>

2.Assign the instance of GridPrintManager to PrintPreviewAreaControl.PrintManagerBase property.

var window = new PreviewWindow
{
    WindowStartupLocation = WindowStartupLocation.CenterScreen,
};
window.PrintPreviewArea.PrintManagerBase = new GridPrintManager(dataGrid);
window.ShowDialog();

3.You can customize print settings like scaling, Orientation at runtime by using PrintPreviewAreaControl.PrintManagerBase and it will be reflected it custom print preview window.

this.PrintPreviewArea.PrintManagerBase.PrintScaleOption = PrintScaleOptions.FitAllRowsonOnePage;
this.PrintPreviewArea.PrintManagerBase.Print();

Custom print preview window in WPF DataGrid

You can get the sample for custom print preview here.