TX Text Control .NET for Windows Forms

Fields, Hyperlinks, and Bookmarks

Topic

Fields mark pieces of text that an application fills, evaluates or links: a customer name taken from a database, a merge field of a Word template, a link to a website or a jump to another place in the same document. A Windows Forms application works with all of them through collections of the TextControl, and users insert hyperlinks and bookmarks with the ribbon.

The examples extend the application of Create Your First Windows Forms Application. Form1.cs needs using TXTextControl;, and each handler belongs to a button that you add in the designer.

Kinds of Fields

A field is a marked piece of text with a name, an ID and events. The base class is TextField, and each kind of field has its own collection:

ClassRepresentsCollection
TextFieldA general field, for example for a database valueTextControl.TextFields
ApplicationFieldA field of MS Word, such as MERGEFIELD or DATETextControl.ApplicationFields
HypertextLinkA link to a target outside the document, such as a URLTextControl.HypertextLinks
DocumentTargetA position in the document, called a bookmark in word processors and an anchor in HTMLTextControl.DocumentTargets
DocumentLinkA link to a document target in the same documentTextControl.DocumentLinks

Two more kinds have pages of their own: form fields, which users fill out, on Form Fields and Conditional Instructions, and PageNumberField, which exists only in headers and footers, on Headers and Footers. The properties of the TextControl return the fields of the text part with the input focus: the main text, a header or footer, or a text frame. To reach the fields of all text parts, loop through TextParts, as Fields and Subtext Parts shows.

Insert and Fill Text Fields

A new field is inserted at the input position. The following handlers insert a field for a customer name and later replace its text:

private void insertFieldButton_Click(object sender, EventArgs e)
{
    TextField customerField = new TextField("Customer name")
    {
        Name = "CustomerName",
        ID = 100,
        HighlightMode = HighlightMode.Activated,
        // Let users type in front of and behind the field
        DoubledInputPosition = true
    };

    if (textControl1.TextFields.CanAdd)
    {
        textControl1.TextFields.Add(customerField);
    }
}

private void fillFieldsButton_Click(object sender, EventArgs e)
{
    foreach (TextField field in textControl1.TextFields)
    {
        if (field.Name == "CustomerName")
        {
            field.Text = "Paul Paulsen";
        }
    }
}

The code works as follows:

  • The TextField constructor takes the visible text. Name and ID identify the field in your code; they are saved with the document in the TX Text Control format (StreamType.InternalUnicodeFormat) and copied with it through the clipboard. Name takes any string, and its length isn't limited, so a field can carry a larger piece of text, such as data of your application.
  • HighlightMode shows the field with a gray background: Activated while the input position is in it, Always, or Never, the default.
  • DoubledInputPosition adds a second input position at the beginning and the end of the field. With the arrow keys, users decide whether the text they type belongs to the field or not.
  • CanAdd is false where no field can be inserted, for example inside another field. TextFieldCollection.Add inserts the field and returns true if it was inserted. The input position moves behind the inserted field.
  • Text reads and replaces the text of the field.

Users can edit the text of a field like any other text. Editable set to false protects the text, and Deleteable set to false prevents that the field is deleted. When the mouse pointer is over a field, it changes to the cursor set with FieldCursor.

Find, List and Remove Fields

private void removeFieldButton_Click(object sender, EventArgs e)
{
    TextField field = textControl1.TextFields.GetItem(100);

    if (field != null)
    {
        // true: keep the text of the field in the document
        textControl1.TextFields.Remove(field, true);
    }
}

private void listAllFieldsButton_Click(object sender, EventArgs e)
{
    StringBuilder list = new StringBuilder();

    foreach (TextField field in textControl1.GetTextFields(TextFieldType.All))
    {
        list.AppendLine(field.GetType().Name + " " + field.Name + ": " + field.Text);
    }

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

StringBuilder needs using System.Text;.

  • GetItem returns the field at the input position, or the field with an ID. Remove deletes a field; with true as the second parameter, its text stays in the document as normal text.
  • GetTextFields returns the fields of one or more kinds, selected with TextFieldType values such as TextField, ApplicationField, HypertextLink, FormFields or All.

TextControl raises events while users work with fields. All of them pass a TextFieldEventArgs with the field in its TextField property:

EventOccurs when
TextFieldCreated, TextFieldDeletedA field is inserted or deleted, also by pasting, undo and redo
TextFieldChangedThe text of a field has changed; formatting changes don't count
TextFieldClicked, TextFieldDoubleClickedThe user clicks or double-clicks a field
TextFieldEntered, TextFieldLeftThe input position moves into or out of a field

Two details of these events:

  • In a TextFieldDeleted handler, the field is already gone from the document. Only TextFieldEventArgs.TextField.ID and .Name still return valid values, so identify the deleted field by one of them.
  • TextFieldDoubleClicked is raised only for fields whose DoubleClickEvent property is true, the default. While it is true, a double-click in the field doesn't select a word as it does in normal text. Set it to false to get the normal word selection and no event.

When a field is copied through the clipboard, the copy has the same name and ID. A TextFieldCreated handler can give the copy a new name.

Work With MS Word Fields

Fields of MS Word documents, such as MERGEFIELD, DATE or IF, are loaded as ApplicationField objects when LoadSettings.ApplicationFieldFormat is set; otherwise the collection stays empty. The following handler loads the merge and date fields of a DOCX template and lists them:

private void loadWordFieldsButton_Click(object sender, EventArgs e)
{
    LoadSettings loadSettings = new LoadSettings()
    {
        // Load MS Word fields as ApplicationField objects
        ApplicationFieldFormat = ApplicationFieldFormat.MSWord,
        ApplicationFieldTypeNames = new string[] { "MERGEFIELD", "DATE" }
    };

    textControl1.Load("template.docx", StreamType.WordprocessingML, loadSettings);

    StringBuilder list = new StringBuilder();

    foreach (ApplicationField field in textControl1.ApplicationFields)
    {
        // For a MERGEFIELD, the first parameter is the field name
        string[] parameters = field.Parameters ?? new string[0];
        list.AppendLine(field.TypeName + " " + string.Join(" ", parameters));
    }

    MessageBox.Show(list.ToString());
}
  • ApplicationFieldTypeNames limits the import to some field types; without it, all MS Word fields are loaded.
  • TypeName is the field type, and Parameters holds the field name and the switches. For MERGEFIELD Address \* Upper, the array contains Address, followed by the switches.

An ApplicationField gives your code access to the type and the parameters of the field, and changing them changes the field in the document. When you change TypeName, change the parameters as well. Text sets the text the field shows. Parameters is a .NET array, which has a fixed size: to add or remove a switch, build a new array and assign it. The following handler shows a text in every Address merge field and removes its \v switch:

private void editWordFieldsButton_Click(object sender, EventArgs e)
{
    foreach (ApplicationField field in textControl1.ApplicationFields)
    {
        string[] parameters = field.Parameters;

        if (field.TypeName != "MERGEFIELD" || parameters == null || parameters[0] != "Address")
        {
            continue;
        }

        // The visible text of the field
        field.Text = "Baker Street, London";

        // Arrays have a fixed size, so copy the other parameters into a new one
        List<string> newParameters = new List<string>(parameters);

        if (newParameters.Remove("\\v"))
        {
            field.Parameters = newParameters.ToArray();
        }
    }
}

List<string> needs using System.Collections.Generic;.

The classes of the TXTextControl.DocumentServer.Fields namespace, such as MergeField and IfField, wrap application fields and give typed access to their settings. To turn all fields into plain text, for example before a document is sent, call ApplicationFieldCollection.Clear with true: it removes the fields and keeps their text.

Merge fields are filled with data by the MailMerge class, and the Reporting tab of the ribbon inserts them without code. Merge Fields covers both.

Word Form Fields and Content Controls

With ApplicationFieldFormat.MSWord, the legacy form fields and content controls of a Word document are loaded as application fields as well, rather than as the form fields of Form Fields and Conditional Instructions. Legacy form fields have the type names FORMTEXT, FORMCHECKBOX and FORMDROPDOWN, and content controls the type name SDTBLOCK. ApplicationFieldFormat.MSWordTXFormFields loads the other Word fields the same way but turns form fields into TX Text Control form fields. Content Controls and Word Form Fields compares the load settings and reads and creates these controls with the field adapter classes. The values of ApplicationFieldFormat, including HighEdit for the fields of the Heiler HighEdit component, are listed in Loading Documents.

Next Steps