TX Text Control .NET for Windows Forms

Creating Documents

Topic

A document your application creates starts empty, in the editor or in a ServerTextControl, and grows from text, snippets and other documents. The button handlers below start a new document in the TextControl of a form, set its page format, assemble it from pieces, combine several files, store its properties and keep the undo history from slowing down large documents.

Create a Document Programmatically is the first tutorial on the subject: it inserts formatted text, a table, an image and a header. How the parts of a document are organized is described in Document Object Model. The examples assume a TextControl named textControl1 on Form1 and these using directives in Form1.cs:

using System;
using System.Windows.Forms;
using TXTextControl;

Start a New Document

In the editor, a new document means removing the current one. ResetContents deletes the entire contents of the TextControl. The page format is a setting of the control, so reset it as well when the new document should start with the defaults:

private void newButton_Click(object sender, EventArgs e)
{
    // Remove the contents and start with the default page format
    textControl1.ResetContents();
    textControl1.ResetPageSize();
    textControl1.ResetPageMargins();
}

ResetPageSize sets US letter pages (8.5 x 11 inches), and ResetPageMargins sets margins of 1 inch. Asking the user before unsaved changes are lost is shown in Load and Save Documents.

A ServerTextControl starts with an empty document. Create must be called before any other member and returns false if the instance couldn't be initialized; a using statement disposes it when the work is done. Using ServerTextControl in Desktop Applications describes its lifecycle.

Set the Page Format

PageSize and PageMargins are measured in the unit of PageUnit, by default 1/100 inch. The following handler shows the current format and then switches to narrow margins and landscape pages:

private void pageFormatButton_Click(object sender, EventArgs e)
{
    // Values in 1/100 inch, the default PageUnit
    MessageBox.Show($"Page size: {textControl1.PageSize.Width} x {textControl1.PageSize.Height}\r\n" +
        $"Margins: {textControl1.PageMargins.Left}, {textControl1.PageMargins.Top}, " +
        $"{textControl1.PageMargins.Right}, {textControl1.PageMargins.Bottom}");

    // Margins of 0.5 inch on every side and landscape orientation
    textControl1.PageMargins = new PageMargins(50, 50, 50, 50);
    textControl1.Landscape = true;
}

The PageMargins constructor takes the left, top, right and bottom margin. Landscape turns the pages. The same properties exist on ServerTextControl. When parts of a document need their own page format, such as one landscape page in a portrait report, divide it into sections, as Sections, Pages, Headers, and Footers describes.

Build a Document From Pieces

The following handler writes a heading and a paragraph with a placeholder and appends an HTML snippet:

private void buildButton_Click(object sender, EventArgs e)
{
    textControl1.ResetContents();

    // Prepare text and formatting in a Selection object, then insert it in one step
    textControl1.Selection = new Selection()
    {
        Text = "Invoice INV-2025-001\r\n",
        FontName = "Arial",
        FontSize = 480, // 24 pt
        Bold = true
    };

    textControl1.Selection = new Selection()
    {
        Text = "Terms: [TERMS]\r\n",
        FontName = "Arial",
        FontSize = 240 // 12 pt
    };

    // Append an HTML snippet in a new paragraph at the end of the document
    textControl1.Append("<p>Thank you for your <strong>order</strong>.</p>",
        StringStreamType.HTMLFormat,
        AppendSettings.StartWithNewParagraph);
}

The code works as follows:

  • Assigning a new Selection object inserts its text with all its attributes at the input position in one step, instead of inserting the text and formatting it afterward. The blog article Speed Up Document Generation by Factor 2 Using Selection Objects in .NET C# measures the difference with ServerTextControl.
  • Append adds a document from a file, a byte array or a string to the end of the existing one. StringStreamType.HTMLFormat reads the string as HTML.

To replace the placeholder with the contents of another document, select it and call Selection.Load, as Load, Append or Insert shows; the same section lists the AppendSettings values.

Combine Several Documents

A cover page and several chapters become one document when you load the first file and append the others. A ServerTextControl does this without showing the intermediate steps, and the editor receives the finished result:

private void combineButton_Click(object sender, EventArgs e)
{
    string[] files = { "cover.docx", "chapter1.docx", "chapter2.docx" };
    byte[] document;

    using (ServerTextControl tx = new ServerTextControl())
    {
        // Initialize the new instance before using it
        if (!tx.Create())
        {
            MessageBox.Show("ServerTextControl could not be initialized.");
            return;
        }

        // The first document replaces the empty contents
        tx.Load(files[0], StreamType.WordprocessingML);

        // Every further document is appended in a new section
        for (int i = 1; i < files.Length; i++)
        {
            tx.Append(files[i], StreamType.WordprocessingML, AppendSettings.StartWithNewSection);
        }

        tx.Save(out document, BinaryStreamType.InternalUnicodeFormat);
    }

    // Show the combined document in the editor
    textControl1.Load(document, BinaryStreamType.InternalUnicodeFormat);
    MessageBox.Show($"Sections: {textControl1.Sections.Count}, pages: {textControl1.Pages}");
}

The code works as follows:

Documents from a database are appended from a byte array in the same way, for example tx.Append(bytes, BinaryStreamType.WordprocessingML, AppendSettings.StartWithNewSection);. Loading Documents compares Load, Append and Selection.Load.

Store Document Properties

DocumentSettings holds the title, author and other general information of the document, which is stored when the document is saved. Set the Properties in Code sets them, and Override Values When Saving replaces them with SaveSettings for one save.

Build Large Documents Without Undo

The editor records each change so that the user can undo it. When your code inserts hundreds of paragraphs, that history costs time and memory: set AllowUndo to false while the code runs, preferably in a try block whose finally sets it back to true, and empty the buffer with ClearUndo afterward if the user shouldn't undo the document step by step. Undo and Redo shows both. A ServerTextControl keeps no undo history at all.

Check the Fonts of a Document

TX Text Control formats text with the fonts available for the formatting device, the printer that FormattingPrinter names. GetSupportedFonts returns their names:

private void fontsButton_Click(object sender, EventArgs e)
{
    string[] fonts = textControl1.GetSupportedFonts();
    MessageBox.Show($"{fonts.Length} fonts available");
}

When a document uses a font that isn't supported, TX Text Control replaces it and, with FontSettings.AdaptFontEvent set to true, raises the AdaptFont event. Choose the Replacement Fonts shows how to find out which fonts were replaced and how to choose the replacements. The syntax block of the reference spells the property AdaptFontsEvent, but the compiled name is AdaptFontEvent. Fonts in the Troubleshooting section helps when text looks different than expected.

Next Steps