TX Text Control .NET for Windows Forms

Load and Save Documents

Topic

An editor becomes useful once users can open their documents and save their work. TextControl brings the Open and Save As dialog boxes with it, and its Load and Save methods also work with files and byte arrays directly. Starting from the form of your first application, the steps below add New, Open, Save and Save As, remember the current file, and ask before unsaved changes are lost.

Prerequisites

  • The application from Create Your First Windows Forms Application, with a TextControl named textControl1 on Form1.
  • Four Button controls on the form, named newButton, openButton, saveButton and saveAsButton. Double-click each one in the designer to create its Click handler. Menu items or ribbon buttons work the same way.

How Loading and Saving Works

Load replaces the complete contents of the editor with a document, and Save writes the complete document. Both come in two kinds of overloads:

  • With a dialog box. Without a file name, Load opens the Open dialog box and Save opens the Save As dialog box. The StreamType values you pass decide which file format filters the dialog offers, and the method returns the DialogResult of the dialog.
  • Without a dialog box. With a file path, a stream, a byte array or a string, the methods load and save directly. Save creates the file or overwrites it.

Supported File Formats lists the formats and their StreamType values.

Add New, Open, Save and Save As

Replace the contents of Form1.cs with the following code, and keep the namespace that Visual Studio created around the class:

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

public partial class Form1 : Form
{
    // The formats offered in the Open and Save As dialog boxes
    private const StreamType DocumentFormats =
        StreamType.WordprocessingML | StreamType.RichTextFormat |
        StreamType.HTMLFormat | StreamType.AdobePDF;

    private string currentFile;            // null until the document has a file
    private StreamType currentStreamType;
    private bool isModified;

    public Form1()
    {
        InitializeComponent();

        textControl1.Changed += textControl1_Changed;
        FormClosing += Form1_FormClosing;

        UpdateCaption();
    }

    private void newButton_Click(object sender, EventArgs e)
    {
        if (!ConfirmSaveChanges())
        {
            return;
        }

        textControl1.ResetContents();

        currentFile = null;
        isModified = false;
        UpdateCaption();
    }

    private void openButton_Click(object sender, EventArgs e)
    {
        if (!ConfirmSaveChanges())
        {
            return;
        }

        LoadSettings loadSettings = new LoadSettings()
        {
            // Import the merge fields of Word documents as fields
            ApplicationFieldFormat = ApplicationFieldFormat.MSWord
        };

        // Show the Open dialog box. Cancel leaves the document unchanged.
        if (textControl1.Load(DocumentFormats | StreamType.AllFormats, loadSettings) != DialogResult.OK)
        {
            return;
        }

        currentFile = loadSettings.LoadedFile;
        currentStreamType = loadSettings.LoadedStreamType;
        isModified = false;
        UpdateCaption();
    }

    private void saveButton_Click(object sender, EventArgs e)
    {
        SaveDocument();
    }

    private void saveAsButton_Click(object sender, EventArgs e)
    {
        SaveDocumentAs();
    }

    private bool SaveDocument()
    {
        // A new document has no file yet
        if (currentFile == null)
        {
            return SaveDocumentAs();
        }

        textControl1.Save(currentFile, currentStreamType);

        isModified = false;
        UpdateCaption();
        return true;
    }

    private bool SaveDocumentAs()
    {
        SaveSettings saveSettings = new SaveSettings();

        // Show the Save As dialog box
        if (textControl1.Save(DocumentFormats, saveSettings) != DialogResult.OK)
        {
            return false;
        }

        currentFile = saveSettings.SavedFile;
        currentStreamType = saveSettings.SavedStreamType;
        isModified = false;
        UpdateCaption();
        return true;
    }

    private void textControl1_Changed(object sender, EventArgs e)
    {
        if (!isModified)
        {
            isModified = true;
            UpdateCaption();
        }
    }

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (!ConfirmSaveChanges())
        {
            e.Cancel = true;
        }
    }

    // Returns false if the user canceled
    private bool ConfirmSaveChanges()
    {
        if (!isModified)
        {
            return true;
        }

        DialogResult result = MessageBox.Show(
            "Do you want to save the changes to the document?",
            "Save Changes",
            MessageBoxButtons.YesNoCancel,
            MessageBoxIcon.Question);

        if (result == DialogResult.Cancel)
        {
            return false;
        }

        if (result == DialogResult.Yes)
        {
            return SaveDocument();
        }

        return true;
    }

    private void UpdateCaption()
    {
        string name = currentFile == null ? "Untitled" : Path.GetFileName(currentFile);
        Text = name + (isModified ? "*" : "") + " - My Editor";
    }
}

The code works as follows:

  • New. ResetContents deletes the complete contents of the editor.
  • Open. Load with StreamType values and a LoadSettings object shows the Open dialog box with the filters of these formats. StreamType.AllFormats adds an All Formats item that shows every file the dialog can open. After the user has opened a file, LoadedFile and LoadedStreamType contain its path and format.
  • Word fields. ApplicationFieldFormat set to MSWord imports the fields of Word and RTF documents, such as merge fields, into ApplicationFields. Without it, the fields are not imported as fields.
  • Save. A document that has a file is saved to it in its format. A new document goes to Save As.
  • Save As. Save with StreamType values and a SaveSettings object shows the Save As dialog box. SavedFile and SavedStreamType contain the path and format the user chose.
  • Unsaved changes. Changed occurs when the contents change. The code marks the document as modified, shows an asterisk in the caption, and asks before New, Open or closing the form discards the changes.

Press F5, type some text and click saveAsButton. Save the document as DOCX, change it, and click newButton: the application asks whether to save the changes.

Load and Save Without a Dialog Box

For files your code knows, pass the path and the format:

textControl1.Load("template.docx", StreamType.WordprocessingML);
textControl1.Save("letter.rtf", StreamType.RichTextFormat);

A document that comes from a database or a web service, or goes into an email attachment, is usually a byte array. Load and Save take it with a BinaryStreamType:

// Load a document from a byte array
byte[] data = File.ReadAllBytes("template.docx");
textControl1.Load(data, BinaryStreamType.WordprocessingML);

// Save the document to byte arrays, as DOCX and as PDF
byte[] docx;
textControl1.Save(out docx, BinaryStreamType.WordprocessingML);

byte[] pdf;
textControl1.Save(out pdf, BinaryStreamType.AdobePDF);

Save creates the arrays, so you do not allocate them.

Save Document Properties

SaveSettings also carries the properties of the document, such as its title and author, and TextControl.DocumentSettings contains the properties of a loaded document. Save the Document as PDF sets them in a first example, and Document Properties explains them in detail.

Add the Commands to the Ribbon

In a ribbon application, New, Open, Save and Save As belong in the Application Menu, the File tab. It has no commands of its own: select the ribbon, open the collection editor of ApplicationMenuItems in the Properties window and add a RibbonButton for each command. Their Click handlers call the same methods as the buttons above.

The TX Words sample installed with the setup implements these commands with a ribbon, in %USERPROFILE%\Documents\TX Text Control 34.0.NET for Windows Forms\CSharp\TX Words\Ribbon.

Next Steps