Content Controls and Word Form Fields
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:
- Setting
Selection.Textinserts text at the input position, and eachAddinserts the next content control after it. - Title and Tag are the title and the tag of the content control that MS Word shows and that other applications use to find the control.
- PlainTextContentControl.Text, DateContentControl.Date and CheckBoxContentControl.Checked set the value of each control.
The base class ContentControlFieldAdapter has the properties that all content controls share:
| Property | Contains |
|---|---|
| Title, Tag | The title and the tag of the content control |
| Id | The ID of the content control |
| ContentEditable, ContentDeletable | Whether the content can be edited and deleted |
| Placeholder | The placeholder part of the content control |
| Type | The type of the content control, as a string |
The six derived classes add the value of their type:
| Class | Value |
|---|---|
| PlainTextContentControl, RichTextContentControl | Text and Text, the text of a control for plain or for formatted text |
| CheckBoxContentControl | Checked |
| ComboBoxContentControl | ListItems, the entries of a list the user can also type into |
| DropDownListContentControl | ListItems, the entries of a list with fixed choices |
| DateContentControl | Date, 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:
- ApplicationField.TypeName tells the kind of field, and the matching adapter is created with the field as its parameter.
- FormFieldAdapter, the base class of the three adapters, has the Name, Text, Enabled, HelpText and StatusText of a form field.
- FormText.MaxLength limits the length of the entry, and FormText.Type says whether it takes regular text, a number, a date, the current date or time, or a calculation.
- FormCheckBox.Checked changes the check box in the document, and FormDropDown.ListEntries holds the entries of the list.
- The handler needs
using System.Text;forStringBuilder.
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
- Forms and Conditional Instructions: create forms from TX Text Control form fields and check their values.
- Fields and Subtext Parts: text fields, hyperlinks, bookmarks and the other Word fields.
- Merge Fields: fill merge fields and form fields with data.
- Loading Documents: the other load settings of Word documents.