Content Controls
A form built in MS Word, such as an order form or a checklist, holds its input elements as content controls or, in older documents, as legacy form fields. When such a DOCX file is loaded into the WPF TextControl, one load setting decides whether they become TX Text Control form fields, whose values are easy to read and set, or MS Word fields that keep Word's own settings, such as the title and tag of a content control. The field adapter classes of TXTextControl.DocumentServer.Fields read and write those settings and create new content controls in code.
The code goes into MainWindow.xaml.cs of a window with a TextControl named textControl1 and a TextBlock named statusText. Form fields created in TX Text Control are covered in Forms and Conditional Instructions, and the other kinds of MS Word fields in Fields and Subtext Parts.
MainWindow.xaml.cs needs these using directives:
using System;
using System.Text;
using System.Windows;
using TXTextControl;
using TXTextControl.DocumentServer.Fields;
What Content Controls and Legacy Form Fields Are
MS Word offers two kinds of input elements for forms:
- Content controls, introduced with MS Word 2007, include rich text, plain text, picture, combo box, drop-down list, check box and date picker controls. Only DOCX files store them; the MS Word 97-2003 format doesn't.
- Legacy form fields are the older text box, check box and drop-down list fields, stored as the fields
FORMTEXT,FORMCHECKBOXandFORMDROPDOWN.
TX Text Control supports both. LoadSettings.ApplicationFieldFormat decides what they become when a document is loaded:
ApplicationFieldFormat | Content controls and legacy form fields become | Other MS Word fields become |
|---|---|---|
None (default) | Form fields in TextControl.FormFields | Not imported as fields |
MSWordTXFormFields | Form fields in FormFields | Application fields |
MSWord | Application fields in TextControl.ApplicationFields | Application fields |
An ApplicationField gives access to the TypeName and the Parameters of a Word field. For content controls and legacy form fields, the parameters are Office Open XML markup. Every content control has the type name SDTBLOCK, and its markup names the kind of control. The adapters described below read and write this markup for you.
Read the Values of a Word Form
To read the values that users entered in MS Word, load the form as form fields. This handler opens order-form.docx and lists each field with its value:
private void ReadWordForm_Click(object sender, RoutedEventArgs e)
{
LoadSettings loadSettings = new LoadSettings()
{
// Content controls and legacy form fields become form fields
ApplicationFieldFormat = ApplicationFieldFormat.MSWordTXFormFields
};
textControl1.Load("order-form.docx", StreamType.WordprocessingML, loadSettings);
StringBuilder values = new StringBuilder();
foreach (FormField field in textControl1.FormFields)
{
switch (field)
{
case CheckFormField checkBox:
values.AppendLine($"{checkBox.Name}: {(checkBox.Checked ? "checked" : "not checked")}");
break;
case DateFormField dateField:
values.AppendLine($"{dateField.Name}: {dateField.Date?.ToShortDateString() ?? "(no date)"}");
break;
default:
// Text boxes, combo boxes and drop-down lists show their value as text
values.AppendLine($"{field.Name}: {field.Text}");
break;
}
}
statusText.Text = values.ToString();
}
A check box content control of the Word form arrives as a CheckFormField, and its Checked property is the state the user set in MS Word. A date picker becomes a DateFormField whose Date is null when no date was entered. Setting these properties and saving the document as DOCX fills the form; Forms and Conditional Instructions shows the other members of the form field classes.
How Field Adapters Work
A field adapter wraps an application field and turns its markup into typed properties: passed an existing application field, it reads and changes that field; created without a parameter, it makes a new field that ApplicationFieldCollection.Add inserts. Use Field Adapters for MS Word Fields explains both directions and how the constant TYPE_NAME chooses the adapter. These adapters handle the form elements of MS Word:
| Adapter | Base class | Wraps | Typed properties |
|---|---|---|---|
| FormText | FormFieldAdapter | A legacy text box | MaxLength, Format, Type (regular text, number, date, current date, current time or calculation) |
| FormCheckBox | FormFieldAdapter | A legacy check box, FORMCHECKBOX | Checked, Size, SizeAuto |
| FormDropDown | FormFieldAdapter | A legacy drop-down list, FORMDROPDOWN | ListEntries |
| PlainTextContentControl, RichTextContentControl | ContentControlFieldAdapter | A plain text or rich text content control | Text |
| CheckBoxContentControl | ContentControlFieldAdapter | A check box content control | Checked |
| ComboBoxContentControl, DropDownListContentControl | ContentControlFieldAdapter | A combo box or drop-down list content control | ListItems of the combo box, ListItems of the drop-down list |
| DateContentControl | ContentControlFieldAdapter | A date picker content control | Date, DateFormat, LanguageID, Calendar, StoreMappedDataAs |
Read and Change Legacy Form Fields
Loaded with ApplicationFieldFormat.MSWord, legacy form fields keep their Word settings, such as the help text shown for a field. This handler lists the legacy form fields of order-form.docx and checks every check box:
private void ReadLegacyFormFields_Click(object sender, RoutedEventArgs e)
{
LoadSettings loadSettings = new LoadSettings()
{
// All MS Word fields, form fields included, become application fields
ApplicationFieldFormat = ApplicationFieldFormat.MSWord
};
textControl1.Load("order-form.docx", StreamType.WordprocessingML, loadSettings);
StringBuilder list = new StringBuilder();
foreach (ApplicationField field in textControl1.ApplicationFields)
{
if (field.TypeName == FormCheckBox.TYPE_NAME)
{
FormCheckBox checkBox = new FormCheckBox(field);
checkBox.Checked = true;
list.AppendLine($"Check box {checkBox.Name}, help text: {checkBox.HelpText}");
}
else if (field.TypeName == FormDropDown.TYPE_NAME)
{
FormDropDown dropDown = new FormDropDown(field);
list.AppendLine($"Drop-down list {dropDown.Name}: {string.Join(", ", dropDown.ListEntries)}");
}
else if (field.TypeName == FormText.TYPE_NAME)
{
FormText textBox = new FormText(field);
list.AppendLine($"Text box {textBox.Name}: {textBox.Text} (up to {textBox.MaxLength} characters)");
}
}
statusText.Text = list.ToString();
}
The code works as follows:
TYPE_NAMEof FormCheckBox,FormDropDownandFormTextis compared with the type name of each field, so the code doesn't depend on how the type names are spelled.- The constructor with an application field connects the adapter to the field in the document. Setting Checked changes that field.
- Name, Text and HelpText belong to the base class
FormFieldAdapter, which also has StatusText, Enabled, CalcOnExit, Font and Bounds, in twips. - The
ApplicationFieldscollection contains the fields of the text part with the input focus. For forms with fields in headers, footers or text frames, loop through TextParts as Fields and Subtext Parts shows.
Save the document with StreamType.WordprocessingML to keep the changed fields as MS Word form fields.
Create Content Controls in Code
The content control adapters create content controls that MS Word shows with their title and tag. This handler inserts a plain text control for the customer name, a date picker for the order date and a check box for the terms, each at the input position:
private void InsertContentControls_Click(object sender, RoutedEventArgs e)
{
textControl1.Text = "";
textControl1.Selection.Text = "Customer: ";
PlainTextContentControl customerName = new PlainTextContentControl()
{
Title = "Customer name",
Tag = "CustomerName",
Text = "Acme Corporation"
};
textControl1.ApplicationFields.Add(customerName.ApplicationField);
textControl1.Selection.Text = "\r\nOrder date: ";
DateContentControl orderDate = new DateContentControl()
{
Title = "Order date",
Tag = "OrderDate",
Date = DateTime.Today
};
textControl1.ApplicationFields.Add(orderDate.ApplicationField);
textControl1.Selection.Text = "\r\nI accept the terms: ";
CheckBoxContentControl termsAccepted = new CheckBoxContentControl()
{
Title = "Terms accepted",
Tag = "TermsAccepted",
Checked = false
};
textControl1.ApplicationFields.Add(termsAccepted.ApplicationField);
// DOCX is the format that keeps content controls
textControl1.Save("order-form.docx", StreamType.WordprocessingML);
}
The code works as follows:
- Each adapter is created with its constructor without parameters, such as the PlainTextContentControl constructor, which creates a new application field.
- ApplicationFieldCollection.Add inserts the field at the input position, and the next
Selection.Textcontinues behind it. - Opened in MS Word, order-form.docx shows three content controls. Loaded again with the default load settings, they are form fields in the
TextControl.
The base class ContentControlFieldAdapter has the properties that all content controls share:
| Property | Contains |
|---|---|
| Title, Tag | The title that MS Word shows and the tag that code uses to find the control |
| Id | The ID of the content control |
| ContentEditable, ContentDeletable | Whether the content can be edited and deleted |
| Type | The type of the content control |
| Placeholder | The placeholder part of the content control |
To change a content control of an existing document, load it with ApplicationFieldFormat.MSWord and pass its application field to the constructor of the adapter of its kind, for example new CheckBoxContentControl(field). The blog article Working with Content Controls in MS Word Documents using TX Text Control in C# shows the import options side by side; its code uses ServerTextControl, whose collections are the same as those of the WPF TextControl.
Merge Data Into Word Forms
A form template can also be filled by a mail merge. MailMerge.FormFieldMergeType decides whether form fields keep their input elements with the merged values preselected or are replaced with the values; Merge Fields describes the options.
Next Steps
- Forms and Conditional Instructions: create, protect and validate forms with TX Text Control form fields.
- Fields and Subtext Parts: the other MS Word fields and their adapters.
- Form Fields and Conditional Instructions: design forms with the Form Fields ribbon tab.
- PDF Forms: turn the form into a fillable PDF.