PrintDocument for WinForms | ComponentOne
PrintDocument Library / Render Objects
In This Topic
    Render Objects
    In This Topic

    All content of a PrintDocument is represented by render objects. A rich hierarchy of render objects  is provided by the RenderObject class to represent different types of content.

    The table below provides a hierarchy of render object types, with a brief description for each class (note that italics indicate abstract classes):

    Render Object Type Description
    RenderObject The base class for all render objects.
    RenderArea Represents a general-purpose container for render objects.
    RenderToc Represents a table of contents.
    RenderC1Printable Represents an external object that can be seamlessly rendered in a C1PrintDocument. (The object must support the IC1Printable interface.)
    RenderEmpty Represents an empty object. Provides a convenient placeholder for things like page breaks and so on where no content needs to be rendered.
    RenderGraphics Represents a drawing on the .NET Graphics object.
    RenderImage Represents an image.
    RenderInputBase The abstract base class for all Preview Forms' input controls. Derived types represent active UI elements embedded in the document when the document is shown by the preview.
    RenderInputButtonBase The abstract base class for button-like input controls (button, check box, radio button).
    RenderInputButton Represents a push button.
    RenderInputCheckBox Represents a checkbox.
    RenderInputRadioButton Represents a radio button.
    RenderInputComboBox Represents a combo box (text input control with a dropdown list).
    RenderInputText Represents a textbox control.
    RenderRichText Represents RTF text.
    RenderShapeBase The abstract base class for classes representing shapes (lines, polygons and so on).
    RenderLineBase The abstract base class for lines and polygons.
    RenderLine Represents a line.
    RenderPolygon Represents a closed or open polygon.
    RenderRectangle Represents a rectangle.
    RenderEllipse Represents an ellipse.
    RenderRoundRectangle Represents a rectangle with rounded corners.
    RenderTable Represents a table.
    RenderTextBase The abstract base class for classes representing text and paragraph objects.
    RenderParagraph Represents a paragraph (a run of text fragments in different styles, and inline images).
    RenderTocItem Represents an entry in the table of contents (RenderToc).
    RenderText Represents a piece of text rendered using a single style.
    RenderBarCode Represents a barcode.

    Add Render Objects

    The visible content of a PrintDocument is represented by a tree of render objects with the root of the tree being the Body of the document. You can add a render object to the Children collection of the document's Body, or to the Children collection of another object already in the hierarchy.

    C#
    Copy Code
    C1PrintDocument doc = new C1PrintDocument();
    RenderText rt = new RenderText();
    rt.Text = "This is a text.";
    doc.Body.Children.Add(rt);
    

    So, the document's Body.Children collection contains all high-level render objects of the document. Moreover, each render object has a Children collection, which contains render objects within it, and so on. (This is quite similar to the Windows Forms' controls that can be nested inside each other. Any control has the collection of contained controls, and so on.)

    In addition to the document's body, there are two other regions where you can add render objects in a document, the page header and footer, which are accessible via the PageHeader and PageFooter properties.

    Render Areas

    Although any render object can contain other render objects as its children, there is one render object designed specifically as a container for other objects, called the RenderArea. The primary difference between a render area and other render objects (such a render text) is that for a render area, specifying either of its width or height as Auto means that the corresponding dimension is determined by the size of the children, while for other types of objects, auto size is determined by the object's own content (text size for a RenderText, image size for a RenderImage, and so on).

    By default, when a new render area is created, its Width is equal to the width of its parent (so a top-level render area stretches across the whole page - or across the current column for multi-column layouts). The Height of a render area, on the other hand, is by default set to Auto (Unit.Auto), and is determined by the combined height of the render area's children. So the default behavior of a top-level render area is to take up the whole page width, and stretch down as needed (possibly spanning multiple pages) to accommodate all its content. You can set the Width of a render area to auto (Unit.Auto), in which case it will adjust to accommodate the combined widths of the area's children. In this case, if the combined width of the area's children exceeds the width of the page, horizontal page breaks will occur, adding extension pages to the right of the current page. To prevent horizontal page breaks (clipping the area on the right if necessary), set the area's CanSplitHorz property to False (it is True by default).

    Stacking

    Within the parent object or document body (that is, the containers), render objects are by default placed according to the stacking rules, determined by the value of the Stacking property of the container (document for top-level objects), which can be one of the following StackingRulesEnum enumeration members:

    Members Description
    BlockTopToBottom Objects are placed one beneath the other within the container. When the bottom edge of the current page is reached, a new page is added. This is the default option.
    BlockLeftToRight Objects are placed one next to the other, from left to right. When the right edge of the current page is reached, a new "horizontal" page is added (a horizontal page logically extends the preceding page to the right; C1PreviewPane shows such pages arranged in a row).
    InlineLeftToRight Objects are placed inline, one next to the other, from left to right. When the right edge of the current page is reached, the sequence wraps to the next line. A new page is added when the bottom of the current page is reached.

    Stacking rules do not propagate down into the contained objects (children). In other words, if you define a render area and set its stacking to the (non-default) value BlockLeftToRight, and then add another render area inside the first one - its stacking will be the default (BlockTopToBottom) unless you explicitly change it.

    You may also use the X and Y properties of a render object to set its position explicitly, which is covered in the next section. Note that in such cases, the render object does not participate in the stacking order at all, so that its position neither affects the positioning of its siblings nor is affected by their positions.

    Specify Render Objects' Size and Location

    The size and location of a render object are controlled significantly by four properties enumerated below:

    All these properties have the value type C1.C1Preview.Unit. The default value for X and Y is Auto (represented by the static field Unit.Auto), which means that the object is positioned according to the stacking rules provided by its parent.

    The following table lists the default sizes (width and height) for all render objects, as well as the rules used to calculate auto sizes:

    Render objects Width Height Auto Size
    RenderArea           Parent width Auto Determined by the combined size of the children.
    RenderToc Parent width Auto Determined by the combined size of the children.
    RenderReport        Parent width Auto Determined by the combined size of the children.
    RenderSection Parent width Auto Determined by the combined size of the children.
    RenderC1Printable Parent width Auto Determined by the combined size of the children.
    RenderEmpty Auto Auto 0
    RenderGraphics Auto Auto Determined by the size of the content.
    RenderImage Auto Auto Determined by the size of the image.
    RenderInputButton Auto Auto Determined by the size of the content.
    RenderInputCheckBox Auto Auto Determined by the size of the content.
    RenderInputRadioButton Auto Auto Determined by the size of the content.
    RenderInputComboBox Auto Auto Determined by the size of the content.
    RenderInputText Auto Auto Determined by the size of the content.
    RenderRichText Parent width (auto width is not supported). Auto (determined by the text size). --
    RenderLine Auto Auto Determined by the size of the shape.
    RenderEllipse Auto Auto Determined by the size of the shape.
    RenderPie  Auto Auto Determined by the size of the shape.
    RenderRoundRectangle Auto Auto Determined by the size of the shape.
    RenderPolygon Auto Auto Determined by the size of the shape.
    RenderArc Auto Auto Determined by the size of the shape.
    RenderRectangle Auto Auto Determined by the size of the shape.
    RenderTable Parent width (auto width is calculated as the sum of columns' widths). Auto Determined by the total width of all columns for width, and by the total height of all rows for height
    RenderParagraph Parent width Auto Determined by the size of the text
    RenderText Parent width Auto Determined by the size of the text
    RenderTocItem Parent width Auto Determined by the size of the text
    RenderField Parent width Auto Determined by the size of the content
    RenderBarCode Auto Auto Determined by the size of the content

    You can override the default values for any of those properties with custom values, and specifying anything but Auto as the value for X or Y coordinates excludes the object from the stacking flow. The size and location properties can be set as absolute values, percentage of parent's size, functions ( such as Min and Max).

    Below are some scenarios showing the use of relative positioning of objects to arrange an image and a text.

    Place text below image

    Let's say you want to place the text below the image simply adding one object after the other to the regular block flow. For such a case, the code snippet is depicted below:

    C#
    Copy Code
    C1PrintDocument doc = new C1PrintDocument();
    RenderText rt = new RenderText("test");
    RenderImage ri = new RenderImage(myImage);
    RenderArea ra = new RenderArea();
    ra.Children.Add(ri);
    ra.Children.Add(rt);
    doc.Body.Children.Add(ra);
    

    Again, let's say you want to place the text below the image while the children are added to the area in inverse order. The code snippet below depicts this:

    C#
    Copy Code
    C1PrintDocument doc = new C1PrintDocument();
    RenderText rt = new RenderText("test");
    RenderImage ri = new RenderImage(myImage);
    RenderArea ra = new RenderArea();
    // place image at the top of the parent:
    ri.Y = 0;
    // place text below next sibling:
    rt.Y = "next.bottom";
    // auto-size text width:
    rt.Width = Unit.Auto;
    ra.Children.Add(rt);
    ra.Children.Add(ri);
    doc.Body.Children.Add(ra);
    

    Place text to the right of image

    Let's say you want to insert the image into the regular block flow, while putting the text to the right of the image, centering it vertically relative to the image. For such a case, the code snippet is depicted below:

    C#
    Copy Code
    C1PrintDocument doc = new C1PrintDocument();
    RenderText rt = new RenderText("test");
    RenderImage ri = new RenderImage(myImage);
    RenderArea ra = new RenderArea();
    ra.Children.Add(ri);
    rt.Width = Unit.Auto;
    // add text after the image:
    ra.Children.Add(rt);
    rt.X = "prev.right";
    rt.Y = "prev.height/2-self.height/2";
    doc.Body.Children.Add(ra);
    

    Also, if you want to place the text to the right of the image, centered vertically, but use the RenderObject.Name in the positioning expressions rather than the relative id "prev", shift the text 2mm towards the right, demonstrating the use of absolute lengths in expressions, the following code snippet can be used.

    C#
    Copy Code
    C1PrintDocument doc = new C1PrintDocument();
    RenderText rt = new RenderText("test");
    RenderImage ri = new RenderImage(myImage);
    RenderArea ra = new RenderArea();
    ri.Name = "myImage";
    rt.Width = "auto";
    rt.X = "myImage.right+2mm";
    rt.Y = "myImage.height/2-self.height/2";
    ra.Children.Add(ri);
    ra.Children.Add(rt);
    doc.Body.Children.Add(ra);
    

    Now, let's say you want to shift the text to the right at least 6cm, using the built-in Max functions. The code snippet below depicts this:

    C#
    Copy Code
    C1PrintDocument doc = new C1PrintDocument();
    RenderText rt = new RenderText("test");
    RenderImage ri = new RenderImage(myImage);
    RenderArea ra = new RenderArea();
    ri.Name = "myImage";
    rt.Width = "auto";
    rt.X = "Max(myImage.right+2mm,6cm)";
    rt.Y = "myImage.height/2-self.height/2";
    ra.Children.Add(ri);
    ra.Children.Add(rt);
    doc.Body.Children.Add(ra);
    

    Align image to the right of page

    Let's say you want to align an image to the right side of the page (utilizing the default value for the width of a render area - parent width), while the text is left-aligned, and centered vertically relative to the image. For this, refer the code snippet below.

    C#
    Copy Code
    C1PrintDocument doc = new C1PrintDocument();
    RenderText rt = new RenderText("test");
    RenderImage ri = new RenderImage(myImage);
    RenderArea ra = new RenderArea();
    ri.Name = "myImage";
    // right-align image:
    ri.X = "parent.right-width";
    // left-align text:
    rt.X = "0";
    rt.Y = "myImage.height/2-height/2";
    ra.Children.Add(ri);
    ra.Children.Add(rt);
    doc.Body.Children.Add(ra);
    

    Render Objects Shadows

    PrintDocument provides support for shadows cast by render objects. For this, the API provides the IShadow interface. By default, the shadow is invisible due to being 100% transparent. To show the shadow. transparency value needs to be set less than 100. Other properties can be adjusted as needed.

    The IShadow interface includes the following sub-properties:

    Render objects Width Height Auto Size
    RenderArea           Parent width Auto Determined by the combined size of the children.
    RenderToc Parent width Auto Determined by the combined size of the children.
    RenderC1Printable Parent width Auto Determined by the combined size of the children.
    RenderEmpty Auto Auto 0
    RenderGraphics Auto Auto Determined by the size of the content.
    RenderImage Auto Auto Determined by the size of the image.
    RenderInputButton Auto Auto Determined by the size of the content.
    RenderInputCheckBox Auto Auto Determined by the size of the content.
    RenderInputRadioButton Auto Auto Determined by the size of the content.
    RenderInputComboBox Auto Auto Determined by the size of the content.
    RenderInputText Auto Auto Determined by the size of the content.
    RenderRichText Parent width (auto width is not supported). Auto (determined by the text size). --
    RenderLine Auto Auto Determined by the size of the shape.
    RenderEllipse Auto Auto Determined by the size of the shape.
    RenderPie  Auto Auto Determined by the size of the shape.
    RenderRoundRectangle Auto Auto Determined by the size of the shape.
    RenderPolygon Auto Auto Determined by the size of the shape.
    RenderArc Auto Auto Determined by the size of the shape.
    RenderRectangle Auto Auto Determined by the size of the shape.
    RenderTable Parent width (auto width is calculated as the sum of columns' widths). Auto Determined by the total width of all columns for width, and by the total height of all rows for height
    RenderParagraph Parent width Auto Determined by the size of the text
    RenderText Parent width Auto Determined by the size of the text
    RenderTocItem Parent width Auto Determined by the size of the text
    RenderBarCode Auto Auto Determined by the size of the content

    The following sample code defines a shadow on a render object:

    C#
    Copy Code
    C1PrintDocument doc = c1PrintDocument1;
    RenderText rt = new RenderText("Sample Shadow");
    rt.Width = Unit.Auto;
    rt.Style.Shadow.Transparency = 20;
    rt.Style.Shadow.Color = Color.BurlyWood;
    doc.Body.Children.Add(rt);
    

    Note that while you do not need to create a Shadow object when setting shadow properties, you may choose to do so, for example, like this:

    C#
    Copy Code
    C1PrintDocument doc = c1PrintDocument1;
    RenderText rt = new RenderText("Sample Shadow");
    rt.Width = Unit.Auto;
    rt.Style.Shadow = new Shadow(20, 100, "1mm", 45, Color.CadetBlue);
    doc.Body.Children.Add(rt);.
    
    Note: Shadows do not affect the objects' sizes for layout purposes.

    Borders

    Borders can be centered over an object's bounds, without affecting either the object's size or the surrounding objects' positions. The BordersModeEdnum specifies the various modes of accounting for border thickness when laying out the objects in a document.

    The BordersModeEnum provides the following options: