TX Text Control .NET for WPF

Loading and Saving Documents

Topic

Where does a document come from, and where does it go? In a WPF editor, the answer is rarely just a file the user picks: documents are read from databases, exchanged as HTML strings, inserted at the cursor or appended as an appendix, and some files fail to load. TextControl handles all of this through its Load and Save methods and the settings objects they accept.

Load and Save Documents in Getting Started builds the basic New, Open, Save and Save As commands. The examples here go further. They assume a TextControl named textControl1 in MainWindow.xaml, and the code goes into MainWindow.xaml.cs with using TXTextControl; and, where noted, using System.IO;.

How Loading and Saving Works

Load replaces everything in the editor with the loaded document, and Save writes the complete document. Which overload you call depends on where the document comes from or goes to, and each kind uses its own enumeration of formats:

Source or targetFormat enumerationExample
A dialog boxStreamType, as file filtersLoad(StreamType.WordprocessingML)
A file pathStreamTypeLoad("report.docx", StreamType.WordprocessingML)
A FileStreamStreamTypeLoad(stream, StreamType.RichTextFormat)
A byte arrayBinaryStreamTypeLoad(data, BinaryStreamType.InternalUnicodeFormat)
A stringStringStreamTypeLoad(html, StringStreamType.HTMLFormat)

A LoadSettings or SaveSettings object can be passed to every overload. It carries options into the operation and brings back information, such as the name of the file the user selected.

Formats and StreamType Values in Supported File Formats lists which format each of the three enumerations offers, and which formats can only be loaded or only be saved.

A loaded PDF document contributes its text, and PDFImportSettings decides how paragraphs or text frames are generated from it; see PDF Import and Its Limitations.

Open and Save With the Built-In Dialog Boxes

The following XAML adds an Open and a Save As button above the editor:

<DockPanel>
    <StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
        <Button Content="Open..." Click="openButton_Click" />
        <Button Content="Save As..." Click="saveAsButton_Click" />
    </StackPanel>
    <WPF:TextControl x:Name="textControl1" />
</DockPanel>

Called without a file name, Load and Save open the Open and Save As dialog boxes; Load() without any parameter offers all supported formats. In WPF, both return a TXTextControl.WPF.DialogResult value, not the DialogResult of Windows Forms: OK when the user confirmed the dialog box, Cancel when it was canceled and None when it was left with the Escape key.

private void openButton_Click(object sender, RoutedEventArgs e)
{
    LoadSettings loadSettings = new LoadSettings()
    {
        // Preselect DOCX in the file type list
        DefaultStreamType = StreamType.WordprocessingML
    };

    TXTextControl.WPF.DialogResult result = textControl1.Load(
        StreamType.WordprocessingML | StreamType.MSWord | StreamType.RichTextFormat |
        StreamType.HTMLFormat | StreamType.InternalUnicodeFormat | StreamType.AllFormats,
        loadSettings);

    if (result == TXTextControl.WPF.DialogResult.OK)
    {
        Title = loadSettings.LoadedFile;
    }
}

private void saveAsButton_Click(object sender, RoutedEventArgs e)
{
    SaveSettings saveSettings = new SaveSettings();

    TXTextControl.WPF.DialogResult result = textControl1.Save(
        StreamType.WordprocessingML | StreamType.HTMLFormat | StreamType.AdobePDF,
        saveSettings,
        SaveSettings.DialogSettings.EnterPassword |
        SaveSettings.DialogSettings.StylesheetOptions |
        SaveSettings.DialogSettings.SaveSelection);

    if (result == TXTextControl.WPF.DialogResult.OK)
    {
        Title = saveSettings.SavedFile;
    }
}

The code works as follows:

  • File filters. The combined StreamType values become the file type filters. StreamType.AllFormats adds an All Formats entry to the Open dialog box, and DefaultStreamType preselects a filter.
  • The chosen file. After OK, LoadedFile and LoadedStreamType, or SavedFile and SavedStreamType, contain the path and format. Keep them for a later Save without a dialog box.
  • Dialog options. SaveSettings.DialogSettings, introduced in version 31.0, adds options that appear only when they apply: EnterPassword a button for an encryption password when PDF is chosen (PDF/A has no encryption passwords), StylesheetOptions a choice between inline styles and a separate CSS file when HTML is chosen, and SaveSelection a check box that saves only the selected text when text is selected.

Control What Is Loaded

Settings on the LoadSettings object change what is imported, for example LoadImages to leave images out or ApplicationFieldFormat to import the merge fields of Word documents. After loading, the same object tells you which file was loaded, its format and its metadata, such as its title and author. Control the Import With LoadSettings lists every setting with its default, and Read Information About a Loaded Document what comes back. Document Properties edits the properties in the editor.

Keep Documents in a Database

A byte array in the TX Text Control format holds everything the editor supports. Use it for documents that are stored and edited again:

// The complete document in the TX Text Control format
byte[] data;
textControl1.Save(out data, BinaryStreamType.InternalUnicodeFormat);

// Store data in the database, and load it again later
textControl1.Load(data, BinaryStreamType.InternalUnicodeFormat);

InternalUnicodeFormat saves text as Unicode and InternalFormat as ANSI. According to the blog article Document Lifecycle Optimization: Leveraging TX Text Control's Internal Format, documents are best kept in this format while they are worked on, and converted to DOCX or PDF only when they are distributed.

HTML, RTF, XML and plain text can also be exchanged as strings:

string html;
textControl1.Save(out html, StringStreamType.HTMLFormat);

textControl1.Load("<p>Hello <b>World</b></p>", StringStreamType.HTMLFormat);

The stream overloads accept a FileStream and read from its current position. Documents in a MemoryStream or another stream go through the byte array overloads.

Save HTML With a Separate Stylesheet

CssSaveMode of the SaveSettings decides whether the formatting of an HTML document is written into its tags, into its head or into a separate CSS file. Save HTML With Stylesheets and Images describes each value and embeds the images. In the Save As dialog box, SaveSettings.DialogSettings.StylesheetOptions lets the user make this choice, as shown above.

Insert, Append and Save Parts of a Document

Load of the Selection inserts a document at the input position or in place of the selected text, and Append adds one at the end; Load, Append or Insert compares them with Load and shows the code. Save of the Selection saves only the selected text, as Save Part of a Document shows; in the Save As dialog box, SaveSettings.DialogSettings.SaveSelection offers the same to the user.

Handle Errors

When a document can't be converted, Load throws a FilterException whose Reason names the cause, such as WrongFileType or InvalidPassword. Catch Errors When Opening a Document shows the try block. InvalidPassword means that a PDF document needs its user password; Load Password-Protected PDF Documents loads it again with the password, and the TX Words sample catches the exception the same way and opens a password dialog box of its own.

Next Steps