Skip to the guide
All guides

Export, print and save the layout of the data grid

Send the rows of MxDataGrid to an Excel workbook, print them with page headers and footers, and save the column layout to load it again later.

app Mordex Components 6.0.0checked reading 6 minutes

On this page

This guide covers three ways to take the grid out of the window. GridExporter writes an Excel workbook. MxDataGridPrintDocument prints the grid. Layout files keep the columns, sort and groups that a user set up.

Export the grid to Excel

GridExporter is in the Mordex.Windows.DataGrid.Export namespace. It writes an Excel XML workbook (SpreadsheetML) to a stream. Excel can open this file. Save it with the .xml extension.

C#
using System.IO;
using Mordex.Windows.DataGrid;
using Mordex.Windows.DataGrid.Export;

using (GridExporter exporter = new GridExporter())
{
    exporter.DataGrid = grid;
    exporter.SheetName = "Employees";

    using (FileStream stream = File.Create(path))
    {
        exporter.Export(stream);
    }
}

The stream stays open after Export. Close it yourself, as the using block above does.

Call Export on the UI thread. The exporter reads the grid directly, so it must run on the thread that owns the grid.

Choose what goes into the file

PropertyDefaultWhat it does
ExportModeAllRowsWhich rows to write: AllRows, SelectedRows or CheckedRows.
IncludeHeaderstrueWrites the column captions as the first row.
IncludeFormatStyletrueKeeps the colors and fonts of the cells.
IncludeCollapsedRowstrueWrites the rows inside closed groups and closed parent rows.
IncludeChildTablesfalseWrites the rows of child tables under their parent rows.
Export options
C#
exporter.ExportMode = ExportMode.SelectedRows;
exporter.IncludeFormatStyle = false;
exporter.IncludeChildTables = true;

IncludeExcelProcessingInstruction is true by default. It adds a line at the top of the file that tells Windows to open the file with Excel.

Keep long numbers exact

Excel keeps only 15 significant digits of a number. ExportValueKind on a column sets how its numbers are written.

  • Automatic writes a number when Excel can hold it exactly. Otherwise it writes the exact value as text. This is the default.
  • Number always writes a number.
  • Text always writes text. Use it for long account numbers and other IDs.
C#
grid.RootTable.Columns["AccountNumber"].ExportValueKind = ExportValueKind.Text;

This setting is saved in the grid layout.

Show progress and cancel an export

The exporter raises ProgressChanged while it works. e.ProgressPercentage gives the percent done, and the last event reports 100. To cancel, pass a CancellationToken to Export. A cancel throws OperationCanceledException.

C#
using System.Threading;

CancellationTokenSource cancel = new CancellationTokenSource();
exporter.ProgressChanged += (sender, e) => progressBar.Value = e.ProgressPercentage;

exporter.Export(stream, cancel.Token);

Because the export runs on the UI thread, cancel from a ProgressChanged handler or from a timer.

A failed export can leave a broken file

If the export fails or is cancelled before it starts to write, the stream stays empty. If it stops while it writes, the stream holds part of a workbook. Write to a temporary file, and move it into place only after Export returns. Delete the temporary file when Export throws.

MxDataGridPrintDocument is a PrintDocument for the grid. It is in the Mordex.Windows.DataGrid namespace. Set DataGrid, then use it with the normal Windows Forms print classes.

C#
using System.Windows.Forms;
using Mordex.Windows.DataGrid;

MxDataGridPrintDocument document = new MxDataGridPrintDocument();
document.DataGrid = grid;
document.PageHeaderCenter = "Employees";
document.PageFooterCenter = "Page [Page #] of [Total Pages]";
document.DefaultPageSettings.Landscape = true;

using (PrintPreviewDialog preview = new PrintPreviewDialog { Document = document })
{
    preview.ShowDialog(this);
}

Call document.Print() to print without a preview. If DataGrid is not set, nothing prints.

The printout always uses dark text on white paper. The theme of the window does not change it. Colors that you set on grid styles are kept.

Add page headers and footers

There are six text areas: PageHeaderLeft, PageHeaderCenter, PageHeaderRight, PageFooterLeft, PageFooterCenter and PageFooterRight. These words in the text are replaced on each page:

TextReplaced with
[Page #]The page number.
[Total Pages]The number of pages.
[Date Printed]The date of printing.
[Time Printed]The time of printing.
[User Name]The name of the Windows user.
Words in page headers and footers

PageHeaderFormatStyle and PageFooterFormatStyle set the font and color of this text. HeaderDistance and FooterDistance set the distance from the edge of the paper, in hundredths of an inch.

Choose what is printed

PropertyDefaultWhat it does
RepeatHeaderstruePrints the column headers on every page.
FitColumnsNoFitZooming shrinks the grid to fit the page width. SizingColumns makes the columns narrower.
PrintCollapsedRowstruePrints the rows inside closed groups.
PrintHierarchicalfalsePrints child tables under their parent rows.
PrintCellBackgroundtruePrints the background color of the cells.
Print options

PrintMode on a column decides if it prints. PrintWhenVisible, the default, prints the column only when it is visible. PrintAlways prints a hidden column too. PrintNever keeps a visible column off the paper.

C#
document.FitColumns = FitColumnsMode.Zooming;
grid.RootTable.Columns["Id"].PrintMode = ColumnPrintMode.PrintNever;

For a card view, CardColumnsPerPage sets how many cards print side by side. The default is 2.

To know the number of pages before printing, call PrepareDocument and then read TotalPages.

Save and load the layout

A layout file holds the settings of the grid and its tables. This includes the order and width of the columns, the sort and the groups. Save it when the form closes and load it when the form opens. Users then find the grid as they left it.

C#
using System.IO;

using (FileStream stream = File.Create(layoutPath))
{
    grid.SaveLayoutFile(stream);
}

using (FileStream stream = File.OpenRead(layoutPath))
{
    grid.LoadLayoutFile(stream);
}

The file is XML. Load it after the grid is bound.

LoadLayoutFile reads the whole file before it changes the grid. A file that is not valid throws an exception, and the grid stays as it was. If a cell edit is not valid, the method throws InvalidOperationException. Correct or cancel the edit first.

C#
try
{
    using (FileStream stream = File.OpenRead(layoutPath))
    {
        grid.LoadLayoutFile(stream);
    }
}
catch (System.Xml.XmlException)
{
    // The file is damaged. Keep the default layout.
}

Keep a layout in memory or as text

GetLayout returns the current layout as a GridLayout object. LoadLayout puts it back.

C#
GridLayout saved = grid.GetLayout();
// Users change the columns here.
grid.LoadLayout(saved);

To store a layout in your own settings, turn it into a string with GetXmlString. Read it back with GridLayout.FromXMLString.

C#
string text = grid.GetLayout().GetXmlString();

GridLayout restored = GridLayout.FromXMLString(text);
grid.LoadLayout(restored);

A simple way to offer a "reset" command is to keep the first layout. Call GetLayout right after you set up the grid, and load it when the user asks.