TX Text Control .NET for WPF

Document Loading and Conversion

Topic

Opening a DOCX file in the WPF TextControl and saving it as PDF looks like two calls, but each call converts the whole document between a file format and TX Text Control's own model. How often a document is converted, how much of it is loaded and on which thread the conversion runs decide whether users wait. Text Control's recommendations and measurements on these points are collected below, with code for a WPF window.

What Loading and Saving Cost

WPF.TextControl.Load, WPF.TextControl.Save and the same methods of ServerTextControl return only when the whole document has been read or written. Called in a handler, they hold the dispatcher for that time. What they cost depends on:

  • The format. DOCX, RTF, HTML and PDF go through TX Text Control's filters, which convert them from and to its document model. The TX Text Control format is that model's own format.
  • What is loaded. Images, links and PDF layouts are optional parts of a document, and LoadSettings can leave them out.
  • The instance. A new ServerTextControl has to be created and initialized before it loads anything; an existing one loads the next document right away.

Keep the TX Text Control Format Until the End

While a document still changes, Text Control recommends keeping it in the TX Text Control format: design templates in it, merge without leaving it, edit and review in it, and convert to PDF or DOCX only when the document is final. The format needs no parsing or conversion, it is a compact binary format smaller than DOCX, and it keeps every feature of TX Text Control. Text Control publishes no measurements for this; the blog article Document Lifecycle Optimization: Leveraging TX Text Control's Internal Format explains the workflow.

The following handlers of a WPF window save and reopen a draft in this format and create the PDF file when the user publishes the document:

using System.Windows;
using TXTextControl;

private void SaveDraft_Click(object sender, RoutedEventArgs e)
{
    // The engine's own format: no conversion
    textControl1.Save("proposal.tx", StreamType.InternalUnicodeFormat);
}

private void OpenDraft_Click(object sender, RoutedEventArgs e)
{
    textControl1.Load("proposal.tx", StreamType.InternalUnicodeFormat);
}

private void Publish_Click(object sender, RoutedEventArgs e)
{
    // One conversion, when the content is final
    textControl1.Save("proposal.pdf", StreamType.AdobePDF);
}

StreamType InternalUnicodeFormat writes the format to a file, and BinaryStreamType InternalUnicodeFormat to a byte array, the form in which documents pass between the editor, a ServerTextControl, a view model or a database.

Load a Quick Preview

LoadSettings decides which parts of a file reach the document. When the user only browses through files, a preview doesn't need all of them. The following handler shows a file from a ListBox named fileList in the editor: of a PDF file only the first page, and of a DOCX file the text without its images:

using System.IO;
using System.Windows;
using System.Windows.Controls;
using TXTextControl;

private void FileList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (fileList.SelectedItem is not string file)
    {
        return;
    }

    if (System.IO.Path.GetExtension(file).Equals(".pdf", System.StringComparison.OrdinalIgnoreCase))
    {
        LoadSettings pdfSettings = new LoadSettings
        {
            // Only the first page, meant for previews
            PDFImportSettings = PDFImportSettings.GenerateTextFramesFirstPageOnly
        };

        textControl1.Load(file, StreamType.AdobePDF, pdfSettings);
    }
    else
    {
        // Images appear as rectangles with their names
        textControl1.Load(file, StreamType.WordprocessingML, new LoadSettings { LoadImages = false });
    }
}

The code works as follows:

  • PDFImportSettings with the value GenerateTextFramesFirstPageOnly works like the default GenerateTextFrames but loads only the first page; the reference suggests it for previewing. GenerateLines imports text only, for searching.
  • LoadImages set to false shows each image as a rectangle with its name. By default, images are loaded.
  • When the user opens the file for editing, load it again with the default settings.

LoadHypertextLinks and LoadDocumentBackColor leave out hypertext links and the background color. Loading Documents lists all settings.

Convert Many Files With One Instance

Every ServerTextControl.Load replaces the document of the instance, so one instance can convert a whole folder, and a new instance doesn't have to be created and initialized for each file. Text Control's text replacement benchmark shows that this pays off: in a loop with the same instance, a document took well under half the time of a single run. Replace Text in Many Large Files gives the numbers, the conditions and the code.

Convert Last and off the Dispatcher

  • Create the PDF file once. A PDF created before the content is final has to be created again; until then, keep the TX Text Control format.
  • Export in the background. Saving a long document as PDF blocks the window when the editor does it. Copy the document into a byte array and let a ServerTextControl create the PDF file on another thread, as Hand a Document to Another Thread shows.
  • Compress images. They take up most of many PDF files; Keep PDF Output Small shows the effect of compression.

Next Steps