# Merge Fields

> Format merge fields in Windows Forms: the Merge Field Options dialog, MergeField number and date formats, DATE fields, FieldMerged, HTML and form fields.

- **Product:** TX Text Control .NET for Windows Forms
- **Section:** Documentation
- **Kind:** Topic
- **Path:** TX Text Control .NET for Windows Forms > Mail Merge and Reporting > Merge Fields
- **5378 words**
- **Web URL:** https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/fields/
- **LLMs URL:** https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/fields/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/fields/llms-full.txt

---

A merge field is more than a name in the template: it carries a format for numbers or dates, text that appears before and after its value and the case of its letters. Users set these options in the **Merge Field Options** dialog box of the **Reporting** tab, and your code sets them with the `MergeField` class. The sections below cover both, add date fields, decide what fields without data show, merge formatted HTML and fill form fields.

Inserting a first merge field with the ribbon and in code is part of the Getting Started tutorial [Create a Template](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/getting-started/mail-merge/template/llms-full.txt), and finding fields without data is part of [Merge Data into Fields](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/getting-started/mail-merge/fields/llms-full.txt). The examples below use the same template, *invoice.docx*, shown in a `TextControl` named `textControl1`.

### The MergeField Class

A merge field is an MS Word `MERGEFIELD` field, stored in the document as an `ApplicationField`. The [MergeField](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-fields/mergefield/llms-full.txt) class of the `TXTextControl.DocumentServer.Fields` namespace is an adapter for such a field: the [constructor](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-fields/mergefield/constructor/llms-full.txt) without parameters creates a new field, and the constructor with an `ApplicationField` wraps an existing one, so that changes to the adapter change the field in the document.

| Property | Sets | In the Merge Field Options dialog |
|---|---|---|
| [Name](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-fields/mergefield/name-property/llms-full.txt) | The name that is matched with the data | **Name** |
| [Text](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-fields/mergefield/text-property/llms-full.txt) | The text the field shows until it's merged | **Text** |
| [TextFormat](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-fields/mergefield/textformat-property/llms-full.txt) | The case of the letters: `Uppercase`, `Lowercase`, `FirstCapital`, `TitleCase` or `None` | **Format** |
| [TextBefore](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-fields/mergefield/textbefore-property/llms-full.txt), [TextAfter](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-fields/mergefield/textafter-property/llms-full.txt) | Text inserted before and after the value | **Text to be inserted before**, **Text to be inserted after** |
| [DateTimeFormat](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-fields/mergefield/datetimeformat-property/llms-full.txt) | A format for dates and times, the MS Word switch `\@` | **Date / time format** |
| [NumericFormat](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-fields/mergefield/numericformat-property/llms-full.txt) | A format for numbers, the MS Word switch `\#` | **Numeric format** |
| [PreserveFormatting](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-fields/mailmergefieldadapter/preserveformatting-property/llms-full.txt) | A flag that `MailMerge` itself doesn't use | **Preserve formatting during updates** |
| [DataSourceCulture](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-fields/mergefield/datasourceculture-property/llms-full.txt), [MergeCulture](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-fields/mergefield/mergeculture-property/llms-full.txt) | The cultures that parse the value and format it, for this field only |  |

The formatting of the field in the template, such as its font and color, is always kept.

### Insert and Edit Fields in the Reporting Tab

Once data is loaded into the Reporting tab, **Select Master Table** in the **Data Source** group chooses the table whose columns the fields come from. **Insert Merge Field** in the **Merge Fields** group then lists the columns of that table, and a click inserts a field at the input position:

![The Insert Merge Field drop-down of the Reporting tab listing the columns of the table Sales_SalesOrderDetail](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-winforms/insert-merge-field-menu.b85ca2d2.webp)

[Merge Fields](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/ribbon-dialogs/#merge-fields) in Reporting Ribbon and Dialog Boxes describes the rest of the drop-down, including the fields of related tables.

**Field Properties** in the same group opens the **Merge Field Options** dialog box for the field at the input position. It has one control for each property of the table above:

![The Merge Field Options dialog box with the field ProductID, its text, a Format drop-down, text before and after, date and time and numeric formats and the Preserve formatting during updates check box](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-winforms/merge-field-options-dialog.178a18c3.webp)

Your code opens the same dialog box with [ShowDialog](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-fields/fieldadapter/showdialog-method/llms-full.txt) of a `MergeField` that wraps the field at the input position, for example from a context menu of your own. [Open the Dialog Boxes From Code](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/ribbon-dialogs/#open-the-dialog-boxes-from-code) shows the handler, which opens the options of merge fields and the other fields of a template.

### Format Numbers and Dates

`NumericFormat` and `DateTimeFormat` take .NET format strings, the standard and custom [numeric format strings](https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings) and [date and time format strings](https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings). For example, a field `Price` with the numeric format `$#,###.00` shows the value 2.4 as $2.40, and a date field with `MMMM d, yyyy` shows September 1, 2026.

The currency symbol, the separators and the names of months depend on the culture that formats the value. [MailMerge.MergeCulture](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/mailmerge/mergeculture-property/llms-full.txt) sets it for all fields and `MergeField.MergeCulture` for a single field; both default to the culture of the current thread, which follows the user's regional settings. Set a culture when the documents must look the same on every computer. The blog article [Format Numeric String Values with MailMerge](https://www.textcontrol.com/blog/2020/10/22/format-numeric-string-values-with-mailmerge/) shows the formats in use.

### Set Formats on All Fields of a Template

Merge fields can be in the main text, in headers and footers and in text frames. [TextControl.TextParts](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/textparts-property/llms-full.txt) contains these parts, and each part has its own `ApplicationFields` collection. The following handler sets formats on the fields of the template in the editor, wherever they are:

```csharp
using System;
using TXTextControl;
using TXTextControl.DocumentServer.Fields;
```

```csharp
private void formatFieldsButton_Click(object sender, EventArgs e)
{
    // The main text, text frames, headers and footers
    foreach (IFormattedText textPart in textControl1.TextParts)
    {
        foreach (ApplicationField applicationField in textPart.ApplicationFields)
        {
            if (applicationField.TypeName != "MERGEFIELD")
            {
                continue;
            }

            MergeField mergeField = new MergeField(applicationField);

            switch (mergeField.Name)
            {
                case "Company":
                    mergeField.TextFormat = TextFormatOptions.Uppercase;
                    break;

                case "InvoiceNumber":
                    mergeField.TextBefore = "Invoice ";
                    break;

                case "Price":
                    mergeField.NumericFormat = "$#,##0.00";
                    break;
            }
        }
    }
}
```

The code works as follows:

- Each text part implements [IFormattedText](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/iformattedtext/llms-full.txt), whose [ApplicationFields](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/iformattedtext/applicationfields-property/llms-full.txt) holds the fields of that part.
- `new MergeField(applicationField)` wraps each merge field, and the new values apply to the field in the document at once.
- After the handler, the company name is merged in capital letters, the invoice number is preceded by "Invoice " and the prices of the `Items` block are shown with a dollar sign and two decimals. Save the template to keep the settings.

### Insert Date Fields

A `DATE` field shows the date of the merge in a format. Users insert one with **Date** in the **Insert Special Field** drop-down of the Reporting tab and choose the format in the **Date Field Options** dialog box:

![The Date Field Options dialog box with a list of date formats, the selected format dddd, d. MMMM yyyy and the Preserve formatting during updates check box](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-winforms/date-field-options-dialog.f63887b2.webp)

In code, the [DateField](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-fields/datefield/llms-full.txt) adapter creates the field:

```csharp
using System;
using System.Globalization;
using TXTextControl.DocumentServer.Fields;
```

```csharp
private void insertDateButton_Click(object sender, EventArgs e)
{
    DateField dateField = new DateField
    {
        Format = "MMMM d, yyyy",
        Culture = CultureInfo.GetCultureInfo("en-US"),
        Date = DateTime.Now
    };

    textControl1.ApplicationFields.Add(dateField.ApplicationField);
}
```

[Format](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-fields/datefield/format-property/llms-full.txt) is a standard .NET date and time format string, [Culture](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-fields/datefield/culture-property/llms-full.txt) the culture that applies it, and [Date](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-fields/datefield/date-property/llms-full.txt) sets the date the field shows in the template. During the merge, the field receives the local date and time of the computer. [MailMerge.DateFieldUtcOffset](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/mailmerge/datefieldutcoffset-property/llms-full.txt) applies an offset from UTC in minutes instead; it is `null` by default.

### Show a Text for Fields Without Data

A field whose name the data doesn't contain is removed, because [RemoveEmptyFields](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/mailmerge/removeemptyfields-property/llms-full.txt) is `true` by default. To show a text instead, keep such fields and change their text in the [FieldMerged](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/mailmerge/fieldmerged-event/llms-full.txt) event, which occurs for every field, with or without data:

```csharp
using System;
using System.IO;
using TXTextControl.DocumentServer;
using TXTextControl.DocumentServer.Fields;
```

```csharp
private void mergeWithPlaceholdersButton_Click(object sender, EventArgs e)
{
    using (MailMerge mailMerge = new MailMerge
    {
        TextComponent = textControl1,
        RemoveEmptyFields = false
    })
    {
        mailMerge.FieldMerged += (s, args) =>
        {
            if (!args.Merged && args.MailMergeFieldAdapter is MergeField mergeField)
            {
                mergeField.Text = "n/a";
            }
        };

        mailMerge.MergeJsonData(File.ReadAllText("invoice.json"));
    }
}
```

[Merged](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/mailmerge-fieldmergedeventargs/merged-property/llms-full.txt) is `false` for a field without data, and [MailMergeFieldAdapter](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/mailmerge-fieldmergedeventargs/mailmergefieldadapter-property/llms-full.txt) is the field, here a `MergeField` whose text becomes "n/a". Add a field named `Phone`, which *invoice.json* doesn't contain, to see the text. [Merge Events](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/events/llms-full.txt) describes the other arguments of the event.

### Merge Formatted Text

A merge field receives plain text. When the data holds formatted text, such as HTML notes, replace the merged content in `FieldMerged`: load the value into a `ServerTextControl`, save it in the internal TX Text Control format and assign the bytes to [MergedField](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/mailmerge-fieldmergedeventargs/mergedfield-property/llms-full.txt). The **Preserve formatting during updates** check box of the Merge Field Options dialog box is a convenient marker for such fields: `MailMerge` ignores it, but your handler can read it as `PreserveFormatting`:

```csharp
mailMerge.FieldMerged += (s, args) =>
{
    // Only fields with "Preserve formatting during updates" checked
    if (args.Merged && args.MailMergeFieldAdapter is MergeField mergeField && mergeField.PreserveFormatting)
    {
        using (ServerTextControl htmlText = new ServerTextControl())
        {
            htmlText.Create();
            htmlText.Load(mergeField.Text, StringStreamType.HTMLFormat);

            byte[] data;
            htmlText.Save(out data, BinaryStreamType.InternalUnicodeFormat);
            args.MergedField = data;
        }
    }
};
```

With a value such as `<p>Thank you for your <strong>business</strong>.</p>` in the data, the merged document shows the text with *business* in bold instead of the HTML tags. The blog article [Reporting: Merge Formatted HTML into Merge Fields](https://www.textcontrol.com/blog/2014/02/10/reporting-merge-formatted-html-into-merge-fields/) introduced this technique with XML data.

### Keep Merge Fields After the Merge

After a merge, a field that received data is gone: its value is ordinary text of the document. That suits a finished letter, but not a document that users edit in the `TextControl` and merge again later, or a preview that should still show the fields. Assign `MergedField` to itself in `FieldMerged`, and the merged fields stay fields with the merged value as their text:

```csharp
using (MailMerge mailMerge = new MailMerge { TextComponent = textControl1 })
{
    // Assigning MergedField to itself keeps the merged fields in the result
    mailMerge.FieldMerged += (s, args) => args.MergedField = args.MergedField;

    mailMerge.MergeJsonData(File.ReadAllText("invoice.json"));
}
```

Fields without data are a separate case: `RemoveEmptyFields` set to `false` keeps them, as [Show a Text for Fields Without Data](#show-a-text-for-fields-without-data) does. The blog article [Merging Templates with MailMerge with Different Merge Field Settings in C#](https://www.textcontrol.com/blog/2023/12/16/merging-templates-with-mailmerge-with-different-merge-field-settings/) compares both settings with screenshots of the results.

### Merge Form Fields

Templates can also contain form fields, such as text boxes, check boxes and drop-downs that users fill in later. [MailMerge.FormFieldMergeType](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/mailmerge/formfieldmergetype-property/llms-full.txt) decides what the merge does with them:

| Value | Form fields |
|---|---|
| `None` (default) | Aren't merged |
| `Preselect` | Keep their controls, and their content is preselected with the data where possible; fields without a matching column stay unchanged |
| `Replace` | Are replaced with the data, so the result contains no form fields; empty form fields are removed according to `RemoveEmptyFields` |

The [FormFieldMerged](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/mailmerge/formfieldmerged-event/llms-full.txt) event reports each form field and whether it received data:

```csharp
using (MailMerge mailMerge = new MailMerge
{
    TextComponent = textControl1,
    FormFieldMergeType = FormFieldMergeType.Preselect
})
{
    mailMerge.FormFieldMerged += (s, args) =>
    {
        if (!args.Merged)
        {
            System.Diagnostics.Debug.WriteLine($"No data for form field {args.FormField.Name}");
        }
    };

    mailMerge.MergeJsonData(File.ReadAllText("invoice.json"));
}
```

With `Preselect`, users see a form in the editor that is already filled out where the data allows it. Data that users must not change belongs in merge fields; values they may correct belong in preselected form fields. [Form Fields](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/form-fields/llms-full.txt) in the Document Editor section describes the form fields themselves, and the blog article [Merging Form Fields using the MailMerge Class](https://www.textcontrol.com/blog/2022/02/21/merging-form-fields-using-the-mailmerge-class/) shows a form template with both kinds of fields.

### Prefixes in Field Names

A dot in a field name addresses related data: `Customer.City` is the value `City` of the nested object or related table `Customer`, and longer paths reach further levels. The prefix `image:` marks a merge field that is merged as an image, as [Images and Barcodes](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/images-barcodes/llms-full.txt) describes.

Prefixes also work inside merge blocks, where they start at the table of the block. The sample database of TX Words has an order table, `Sales_SalesOrderHeader`, which is related to the order lines in `Sales_SalesOrderDetail`, and each order line to a product in `Production_Product`:

![Three related tables: Sales_SalesOrderHeader connected to Sales_SalesOrderDetail by SalesOrderID, and Sales_SalesOrderDetail connected to Production_Product by ProductID.](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-winforms/prefixed-fields-data-model.8f9f5d44.webp)

With `Sales_SalesOrderHeader` as the master table, a merge block `Sales_SalesOrderDetail` repeats the order lines. Inside it, `OrderQty`, `UnitPrice` and `LineTotal` need no prefix, because they are columns of the block's own table, while `Production_Product.ProductNumber` and `Production_Product.Name` take the number and the name of the product of the current line.

![A table row merge block with the fields ProductNumber, Name, OrderQty, UnitPrice and LineTotal and an image placeholder, highlighted in red.](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-winforms/merge-block-row-template.df401d03.webp)

A path can follow several relations in a row. The product photo of each order line is an image placeholder in the same block, and its name leads from the product through the table that links products and photos to the photo itself:

```text
Production_Product.Production_ProductProductPhoto.Production_ProductPhoto.ThumbNailPhoto
```

Each part before the last is a related table, and `ThumbNailPhoto` is the column with the image data. `MailMerge` follows the relations by itself; you pass only the master table. The **Insert Merge Field** drop-down offers related tables as submenus and inserts their fields with the prefix, as [Reporting Ribbon and Dialog Boxes](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/ribbon-dialogs/#merge-fields) shows.

The merged invoice shows the order, its lines with the product numbers and names and the product photos, all filled from the related tables:

![A merged payment invoice with the sender and customer addresses, two order lines with product code, name, quantity, prices and a photo of a bike, and the totals below.](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-winforms/prefixed-fields-invoice.151ed6dc.webp)

### Next Steps

- [Conditional Content](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/conditional-content/llms-full.txt): insert text with `IF` fields depending on the data.
- [Formatting and Styling](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/styling/llms-full.txt): format merged cells and rows.
- [Merge Blocks](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/blocks/llms-full.txt): repeat fields for each record of a list.
- [Reporting Ribbon and Dialog Boxes](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/ribbon-dialogs/llms-full.txt): the other commands of the Reporting tab.

---

## Nearby

- **Previous:** [Data Source Configuration Files](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/data-sources/configuration-files/llms-full.txt)
- **Next:** [Merge Blocks](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/blocks/llms-full.txt)
