![]() |
Desktop Development »
Grid & Data Controls »
Grid controls
Beginner
License: The Eclipse Public License 1.0
Printing a DataGridView on DotNet FrameworkBy BlaiseBrayeThis library provide DataGridView printing features on the FrameWork .NET 3.5. (C# VB F#) |
C# (C# 3.0), VB (VB 9.0), Windows (Win2K, WinXP, Win2003, Vista), .NET (.NET 3.5), GDI+, LINQ, Dev
|
||||||||
|
Advanced Search |
|
|
|
||||||||||||||||
The DataGridView control is a very powerful tool to display data in tabular format. However, a printing method was not incorporated into the control which presents the developer to create or devise a method to easily print the contents of the DataGridView.
DataDrawer is a class DLL to easily provide DataGridView printing. The library is written in C# with a version for .NET 3.5 incorporating LINQ and a .NET 2.0 versions. The library supports the C++, C#, VB.NET, and F# development environments.
The Class Library DLL provides the developer with a seamless approach to achieve DataGridView printing.
The DLL implements the following features:To make the print job flow smoothly, one basic idea has been to create a Coding Line within the project:
The DataGridView has a number of Levels which are cut into Partitions. A Level identifies a number of rows which can be printed on a sheet. A Partition is the number of columns which can be printed on a sheet.
With this concept, it is very easy to make some calculations and having a set of partitions which cover the DataGridView.
![]() |
This class implements the print job, adds functionality to the DataGridView and its components. The Font, ColumnWidth, HeaderHeight and RowHeight functions have some overloads which use a "scale" parameter. The “scale” parameter is the core of the "FitColumnsToPage" functionality. The code was designed to provide a uniform or similar approach to the form of the Functions: public static Color ForeColor(this DataGridViewCell cell)
{
if (cell.HasStyle && cell.Style.ForeColor != Color.Empty) return cell.Style.ForeColor;
else return cell.InheritedStyle.ForeColor;
}
public static Color BackColor(this DataGridViewCell cell)
{
if (cell.HasStyle && cell.Style.BackColor != Color.Empty) return cell.Style.BackColor;
else return cell.InheritedStyle.BackColor;
}
Utilizing this approach to coding the functions should minimize initialize a style when it is not required. See Cell Styles in the Windows Forms DataGridView Control on MSDN |
![]() |
Usefull to keep track of the printable coordinates of a document; public static DocumentMetrics FromPrintDocument(PrintDocument printDocument)
{
PageSettings pageSettings = printDocument.DefaultPageSettings;
return new DocumentMetrics()
{
Width =
(pageSettings.Landscape)
?pageSettings.PaperSize.Height:pageSettings.PaperSize.Width,
Height =
(pageSettings.Landscape)
?pageSettings.PaperSize.Width:pageSettings.PaperSize.Height,
LeftMargin = pageSettings.Margins.Left,
TopMargin = pageSettings.Margins.Top,
RightMargin = pageSettings.Margins.Right,
BottomMargin = pageSettings.Margins.Bottom
};
}
|
|
The PartitionBounds Class contains the bounds of the number of partitions that were split from the DataGridView, i.e., the included rows and columns of a partition as well as the coordinate information of the bounds (size). This class could have been named PartitionMetrics but there might be some confusion with DocumentMetrics. |
|
The Patition class represents the portion of a DataGridView which can be printed on a single sheet. // code showing how rows are returned by this class
public DataGridViewRow GetRow(int i)
{
return GridView.Rows[Bounds.StartRowIndex + i];
}
public IEnumerable
|
This class isolates the title, header, and footer printing from the library.
3-PrintBlock objects are defined in GridDrawer: TitlePrintBlock, SheetFooter, and SheetHeader.
These PrintBlock objects are defined by extending the PrintBlock class.
Described below is the approach to implement title, header, and footer printing with the library. You call the GetSize method first which sets a Rectangle in which the Draw method will print. This allows us to define some blocks to be printed without modifying the library core.
The Draw function receives a Dictionary parameter containing information from the CodeEnum enumeration for the Page number, page count, date, and time.
Note. There is a reusable TitlePrintBlock class already implemented in Lib.GridDraw.Tools. See "Working with this library" section for more detail on how this works.
public class TitlePrintBlock : PrintBlock
{
public String Title { get; set; }
public Color ForeColor { get; set; }
public Font Font { get; set; }
public StringFormat Format { get; set; }
public override SizeF GetSize(Graphics g, DocumentMetrics metrics)
{
return g.MeasureString(Title, Font, metrics.PrintAbleWidth, Format);
}
public override void Draw(Graphics g, Dictionary codes)
{
g.DrawString(Title, Font, new SolidBrush(ForeColor), Rectangle, Format);
}
}
The core of the library is the GridDrawer class. GridDrawer exposes the properties and methods of the class. Using this class should be straight forward and easily implemented into your code.
All partitions are calculated and created in a single instance. Partitions are set from information calculated during the Initialization process or step.
public class HeaderPrintBlock : PrintBlock
{
float imgHeight = 75;
public override SizeF GetSize(Graphics g, DocumentMetrics metrics)
{
return new SizeF(metrics.PrintAbleWidth, imgHeight + 2); //+2 for spacing with document
}
public override void Draw(System.Drawing.Graphics g, Dictionary codes)
{
GraphicsUnit units = GraphicsUnit.Pixel;
RectangleF rec = Properties.Resources.logo.GetBounds(ref units);
float scale = imgHeight / rec.Height;
// as you can see below, we are using the base.Rectangle.property which has been set by GridDrawer Class
// after it knows The Size of this block.
g.DrawImage(Properties.Resources.logo, new RectangleF(Rectangle.X, Rectangle.Y, rec.Width * scale, imgHeight));
}
}
public class FooterPrintBlock : PrintBlock
{
Font font = new Font("Tahoma", 9, GraphicsUnit.Point);
public override SizeF GetSize(Graphics g, DocumentMetrics metrics)
{
return g.MeasureString("Page X Of Y", font);
}
public override void Draw(System.Drawing.Graphics g, Dictionary codes)
{
StringFormat format = new StringFormat();
format.Trimming = StringTrimming.Word;
format.FormatFlags = StringFormatFlags.NoWrap;
format.Alignment = StringAlignment.Far;
// as you can see below, we are using the codes param to know on which page we are for instance.
g.DrawString(
string.Format("Page {0} Of {1}", codes[CodeEnum.SheetNumber], codes[CodeEnum.SheetsCount]),
font,
new SolidBrush(Color.Black),
Rectangle,
format);
}
}
TitlePrintBlock titleBlock = new TitlePrintBlock(printDocument.DocumentName,Color.DarkBlue);
printProvider = Tools.PrintingDataGridViewProvider.Create(
printDocument,
GridView, chkCenter.Checked, chkFitColumns.Checked,
new TitlePrintBlock(printDocument.DocumentName,Color.DarkBlue),
new PrintBlocks.HeaderPrintBlock(),
new PrintBlocks.FooterPrintBlock());
I hope you enjoy GridDraw.NET. Do not hesitate providing your feedback. It has been a pleasure to create and contribute this project to the community.
This is the first project I have written with .NET 3.5, using Linq. Understanding and using Linq simplified the source code.
I whish to thank Salan Al-Ani for his CodeProject article
and to codeplex.com for providing source control feature for the GridDrawer Library.
I whish also to thank Marc Miller, he has reviewed whole parts of this article and corrected most of it grammar.
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 27 Apr 2008 Editor: |
Copyright 2008 by BlaiseBraye Everything else Copyright © CodeProject, 1999-2009 Web20 | Advertise on the Code Project |