TX Text Control .NET for Windows Forms

Content Controls and Word Form Fields

Topic

Forms and templates made in MS Word hold two kinds of controls: content controls, such as plain text boxes, check boxes, drop-down lists and date pickers, and the older legacy form fields FORMTEXT, FORMCHECKBOX and FORMDROPDOWN. TX Text Control .NET for Windows Forms loads both. Depending on a load setting, they become form fields that users fill out in the TextControl, or application fields that keep all Word-specific settings, such as the title and tag of a content control, and that the field adapter classes of TXTextControl.DocumentServer.Fields make accessible in code.

The handlers go into Form1.cs with the TextControl named textControl1 and need using TXTextControl; and using TXTextControl.DocumentServer.Fields;. Form fields that you create in TX Text Control itself are the subject of Forms and Conditional Instructions, and fields in general of Fields and Subtext Parts.

How Word Controls Are Loaded

Content controls exist since MS Word 2007 and replace the legacy form fields; both are stored in DOCX files. Of the MS Word formats, only DOCX carries content controls: the MS Word 97-2003 format doesn't support them. When you load a document, LoadSettings.ApplicationFieldFormat decides what becomes of them:

With the default None and with MSWordTXFormFields, content controls and legacy form fields become form fields in FormFields; with MSWord, they become application fields in ApplicationFields. Control the Import With LoadSettings lists all values of ApplicationFieldFormat and what they do with the other Word fields.

Choose form fields when users fill out the form in the editor or your code reads and sets its values: they are the TextFormField, CheckFormField, SelectionFormField and DateFormField objects that Form Fields and Conditional Instructions describes, and they are saved back to DOCX as content controls. Choose application fields when your code needs what only Word knows about a control, or when it creates Word controls itself. The rest of this page works with application fields.

Field Adapters

An ApplicationField stores a Word field or control as its type name and its parameters, which are written in the XML syntax of Office Open XML. A field adapter wraps an application field and offers its settings as typed properties, so that your code doesn't parse that XML. Every adapter derives from FieldAdapter:

FieldAdapter
+-- MailMergeFieldAdapter        MergeField, IfField, IncludeText, DateField, NextField, NextIfField
+-- FormFieldAdapter             FormText, FormCheckBox, FormDropDown
+-- ContentControlFieldAdapter   PlainTextContentControl, RichTextContentControl, CheckBoxContentControl,
                                 ComboBoxContentControl, DropDownListContentControl, DateContentControl

Each adapter class has two constructors. Without a parameter, it creates a new field, whose ApplicationField you add to the document. With an existing ApplicationField, it wraps that field, and every property you set changes the field in the document. FieldAdapter.ShowDialog opens the options dialog box of a field; pass your form as the owner window. The merge field adapters are covered in Merge Fields, Conditional Content and Subtemplates.

Create Content Controls

To add a content control, create the adapter of its type, set its properties and add its application field at the input position with ApplicationFieldCollection.Add. The following handler writes a small form with a text box, a date picker and a check box and saves it as DOCX:

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

    textControl1.Selection.Text = "Customer: ";
    PlainTextContentControl customerName = new PlainTextContentControl()
    {
        Title = "Customer name",
        Tag = "CustomerName",
        Text = "Acme Corporation"
    };
    textControl1.ApplicationFields.Add(customerName.ApplicationField);

    textControl1.Selection.Text = "\nOrder date: ";
    DateContentControl orderDate = new DateContentControl()
    {
        Title = "Order date",
        Tag = "OrderDate",
        Date = DateTime.Today
    };
    textControl1.ApplicationFields.Add(orderDate.ApplicationField);

    textControl1.Selection.Text = "\nTerms accepted: ";
    CheckBoxContentControl termsAccepted = new CheckBoxContentControl()
    {
        Title = "Terms accepted",
        Tag = "TermsAccepted",
        Checked = false
    };
    textControl1.ApplicationFields.Add(termsAccepted.ApplicationField);

    // Content controls are kept in DOCX files
    textControl1.Save("order-form.docx", StreamType.WordprocessingML);
}

The code works as follows:

The base class ContentControlFieldAdapter has the properties that all content controls share:

PropertyContains
Title, TagThe title and the tag of the content control
IdThe ID of the content control
ContentEditable, ContentDeletableWhether the content can be edited and deleted
PlaceholderThe placeholder part of the content control
TypeThe type of the content control, as a string

The six derived classes add the value of their type:

ClassValue
PlainTextContentControl, RichTextContentControlText and Text, the text of a control for plain or for formatted text
CheckBoxContentControlChecked
ComboBoxContentControlListItems, the entries of a list the user can also type into
DropDownListContentControlListItems, the entries of a list with fixed choices
DateContentControlDate, DateFormat, LanguageID and Calendar

To read the title and tag of the content controls of an existing document, load it with ApplicationFieldFormat.MSWord and pass each application field to the constructor of the adapter class of its type. The blog article Working with Content Controls in MS Word Documents using TX Text Control in C# shows both ways of loading, and Form Field Compatibility: Work with AcroForms, Legacy MS Word Forms, and Content Controls compares the kinds of form fields.

Read and Change Legacy Form Fields

The legacy form fields of MS Word are application fields with the type names FORMTEXT, FORMCHECKBOX and FORMDROPDOWN. Their adapters are FormText, FormCheckBox and FormDropDown. The following handler loads a Word form, lists every legacy form field with its value and checks all check boxes:

private void readLegacyFormFieldsButton_Click(object sender, EventArgs e)
{
    LoadSettings loadSettings = new LoadSettings()
    {
        // Keep legacy form fields as application fields
        ApplicationFieldFormat = ApplicationFieldFormat.MSWord
    };

    textControl1.Load("legacy-form.docx", StreamType.WordprocessingML, loadSettings);

    StringBuilder list = new StringBuilder();

    foreach (ApplicationField field in textControl1.ApplicationFields)
    {
        switch (field.TypeName)
        {
            case "FORMTEXT":
                FormText textBox = new FormText(field);
                list.AppendLine($"{textBox.Name}: \"{textBox.Text}\", at most {textBox.MaxLength} characters");
                break;

            case "FORMCHECKBOX":
                FormCheckBox checkBox = new FormCheckBox(field);
                checkBox.Checked = true;
                list.AppendLine($"{checkBox.Name}: checked");
                break;

            case "FORMDROPDOWN":
                FormDropDown dropDown = new FormDropDown(field);
                list.AppendLine($"{dropDown.Name}: {string.Join(", ", dropDown.ListEntries)}");
                break;
        }
    }

    MessageBox.Show(list.ToString());
}

The code works as follows:

Save the document as DOCX afterward to keep the changed values.

NEXT and NEXTIF Fields

Two more Word fields steer a mail merge rather than hold a value. A NEXT field moves on to the next record of the data, so that one copy of a merge block shows two or more records, for example to alternate the color of table rows as Formatting and Styling shows. A NEXTIF field does this only when a comparison is true. Users insert both with Insert Special Field on the Reporting tab, as Reporting Ribbon and Dialog Boxes describes.

In code, NextField creates and reads a NEXT field. The following line inserts one at the input position, for example at the end of the first of two table rows in a merge block:

// Continue with the next record of the merge block
textControl1.ApplicationFields.Add(new NextField().ApplicationField);

NextIfField adds the comparison. Expression1 must be the name of a data field for the merge, Expression2 is the value it is compared with, and Operator the comparison: Equals, NotEqual, LessThan, GreaterThan, GreaterThanOrEqualTo or LessThanOrEqualTo. Result holds the outcome of the comparison. DataSourceCulture and MergeCulture set the cultures used to compare numbers and to format values; both default to the culture of the current thread.

DocumentController

The reference of this product also lists DocumentController, with its FieldAdapterCollection of field adapters: it handles documents on the server for the legacy ASP.NET Web Forms Document Viewer of TX Text Control .NET Server and isn't needed in a Windows Forms application.

Next Steps