Two important classes are introduced in this article.
-
ReportDocument
- a class that inherits from PrintDocument and greatly assists in printing tabular reports consisting of data from a DataTable. -
PrintControl
- a control that simplifies the process of guiding the user through the printing process.
The section on the ReportDocument includes many helper classes to define sections, columns, and text styles. The PrintControl section includes a brief description of some of the dialogs used in the printing process.
Latest documentation - NDOC generated documentation.
There are several classes introduced into the ReportPrinting namespace. They work together for the printing of the above report (in addition to all the .NET Framework base classes that are used). Here is a quasi-UML diagram that shows the relationship between these classes. An open triangle is generalization (i.e. it points to the super-class in the inheritance chain). The black diamonds are composite (i.e. shows that one class instantiates members of another class). The dashed-lines are dependency (i.e. it uses the class).
ReportDocument
ReportDocument
extends from PrintDocument
and is customized for printing reports from one or more tables of data. A ReportDocument
object is the top-level container for all the sections that make up the report. (This consists of a header, body, and footer.)
The ReportDocument's main job is printing, which occurs when the Print()
method is called of the base class. The Print()
method iterates through all the ReportSections
making up the document, printing each one.
The strategy design pattern is employed for formatting the report. An object implementing IReportMaker
may be associated with the ReportDocument
. This IReportMaker
object is application specific and knows how to create a report based on application state and user settings. This object would be responsible for creating sections, associating DataViews
, and applying any required styles through use of the TextStyle
class. It will generally use the ReportBuilder
class to assist with the complexity of building a report.
ReportSection
ReportSection
is an abstract class that represents a printable section of a report. There are several subclasses of ReportSection
, including ReportSectionText
(which represents a string of text) and ReportSectionData
(which represents a printable DataView
). There are also container sections (which derive from SectionContainer
class, which in turn derives from ReportSection
). These containers hold child ReportSection
objects (also known as subsections) to be printed. Lets take a quick look at how this might work with an example.
In the sample report shown at the top of this article, there is a paragraph of text followed by a table of data. (There are actually two paragraphs of text, one of which is a heading. Plus there is a page header, but well ignore all that for now.) We would create a ReportSectionText
object to print the paragraph of text and a ReportSectionData
object to print the table of data. To add both of these ReportSections
to the ReportDocument
, we must create a container. We would create a LinearSections
container to hold these two sections. This container is then made the body of the ReportDocument
. When the document is printed, the section container will first print the ReportSectionText
, and then below that, it will print the ReportSectionData
. Simply simply printing each section below the preceding one will result in the finished report. But there are many other ways to set up these classes.
SectionContainer
This abstract class defines a container of sections. There are two types provided with the framework: LinearSections
and LayeredSections
.
LinearSections
The LinearSections
class is a subclass of SectionContainer
, which is a subclass of ReportSection
. Therefore, the LinearSections
can be thought of as "a printable section of a report." However, it is also a container of one or more sections.
As its name implies, it lays sections out linearly -- that is, in a row or in a column. A property named Direction specifies if this container will layout sections going down the page (typical) or across the page (not as typical).
(see Layouts for more information about how this class works.)
LayeredSections
The LayeredSections
class is also a subclass of SectionContainer
, which is a subclass of ReportSection
. Therefore, the LayeredSections
can be thought of as "a printable section of a report." It is also a container of one or more sections.
The child sections of a LayeredSections
object are all painted on top of one another (creating layers). The first section added to a LayeredSections
object is the bottom layer. Subsequent ReportSection
objects added to the LayeredSections
object will be shown on top of each other.
(see Layouts for more information about how this class works.)
SectionText
The SectionText
prints a string to the page. Two public properties are used to setup this section. Text is used to specify the string to print. TextStyle, described later, sets the font, color, alignment and other properties for the how the text is printed.
It is interesting to note that the string specified for this section can be just one word, or many paragraphs of text.
SectionTable
The SectionTable
prints a table of data. It uses a DataView
object (from the .NET System.Data
namespace) as the source of data. It then uses a series of ReportDataColumns
to provide the fomatting details. These ReportDataColumns
are similar to the DataGridColumnStyle
class. Table wide formatting includes setting Header, Row, and Alternating row TextStyle's, along with setting the width and margins.
ReportDataColumn
The ReportDataColumn
provides the necessary information for formatting data for a column of a report. For every column to be presented within a section of data, a new ReportDataColumn
object is instantiated and added to the ReportSection
. At a minimum, each column describes a source field from the DataSource
(that is, a column name from the DataView) and a maximum width on the page.
The ReportDataColumn
can be setup with its own unique TextStyle
for both header and normal rows. Therefore, each column's data can be formatted differently (e.g. an important column could be bold and red). The TextStyle
is also used to set the horizontal alignment (justification).
TextStyle
The TextStyle
class allows styles and fonts to be added to text selectively, allowing default styles to be used when not explicitly set. All styles (except for the static TextStyle.Normal
) have another style as their "default" style. Until a property is set (like bold, underline, size, font family, etc), a TextStyle
object always uses the corresponding value from its default (or parent) style.
For example, a new style can be defined using Normal as its default, but setting bold.
TextStyle paragraphStyle = new TextStyle(TextStyle.Normal);
paragraphStyle.Bold = true;
It will have all the same properties as TextStyle.Normal
, except it will be bold. A later change to Normal
(such as below) will have the effect of increasing the size of both styles (Normal and paragraphStyle).
TextStyle.Normal.Size += 1.0f
Comments