# Reading Form Fields and Values

> Get the values of a returned PDF form in Windows Forms with GetAcroFormFields: FormTextField, FormCheckBox and FormChoiceField, copied into the TextControl.

- **Product:** TX Text Control .NET for Windows Forms
- **Section:** Documentation
- **Kind:** Topic
- **Path:** TX Text Control .NET for Windows Forms > PDF Processing > PDF Forms > Reading Form Fields and Values
- **3512 words**
- **Web URL:** https://docs.textcontrol.com/tx-text-control-dotnet-winforms/pdf/forms/reading-fields/
- **LLMs URL:** https://docs.textcontrol.com/tx-text-control-dotnet-winforms/pdf/forms/reading-fields/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/tx-text-control-dotnet-winforms/pdf/forms/reading-fields/llms-full.txt

---

A PDF form that comes back filled in carries data: a name, a selected country, a check mark. `Forms.GetAcroFormFields` reads this data from the PDF file or from a byte array, without loading the document into the editor. A Windows Forms application can show the values, store them or put them back into its own form, for example to let a clerk check and correct what a customer entered.

The examples read *form-filled.pdf*, the form of [Create a PDF Form](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/getting-started/pdf/form/llms-full.txt) with its fields `name`, `country` and `newsletter`, after a user filled it in and saved it in a PDF reader. How such forms are created is described in [Creating AcroForms](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/pdf/forms/acroforms/llms-full.txt).

### How GetAcroFormFields Reads a Form

[Forms.GetAcroFormFields](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-pdf/forms/getacroformfields-method/llms-full.txt) is a static method of the `TXTextControl.DocumentServer.PDF` namespace, introduced in version 29.0. One overload takes the path of a PDF file, the other the PDF as a byte array. It returns an array of [FormField](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-pdf/acroforms-formfield/llms-full.txt) objects of the `TXTextControl.DocumentServer.PDF.AcroForms` namespace, each of the class that fits its field:

| Class | Field in the PDF | Value |
|---|---|---|
| [FormTextField](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-pdf/acroforms-formtextfield/llms-full.txt) | Text field; also the date form fields of TX Text Control | [Value](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-pdf/acroforms-formtextfield/value-property/llms-full.txt): the text entered |
| [FormCheckBox](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-pdf/acroforms-formcheckbox/llms-full.txt) | Check box | [IsChecked](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-pdf/acroforms-formcheckbox/ischecked-property/llms-full.txt) |
| [FormRadioButton](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-pdf/acroforms-formradiobutton/llms-full.txt) | Radio button, derived from `FormCheckBox` | `IsChecked` |
| [FormChoiceField](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-pdf/acroforms-formchoicefield/llms-full.txt) | The base class of combo boxes and list boxes | [Value](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-pdf/acroforms-formchoicefield/value-property/llms-full.txt): the selected item; [Options](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-pdf/acroforms-formchoicefield/options-property/llms-full.txt): all items |
| [FormComboBox](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-pdf/acroforms-formcombobox/llms-full.txt) | Combo box or drop-down list, derived from `FormChoiceField` | `Value` |
| [FormListBox](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-pdf/acroforms-formlistbox/llms-full.txt) | List box, derived from `FormComboBox` | `Value` |
| [FormButton](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-pdf/acroforms-formbutton/llms-full.txt) | Push button | None |

Every field has these members of the base class:

- **[FieldName](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-pdf/acroforms-formfield/fieldname-property/llms-full.txt)** is the name the author of the form gave the field, for TX Text Control forms the `Name` of the form field.
- **[AlternateFieldName](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-pdf/acroforms-formfield/alternatefieldname-property/llms-full.txt)** is the alternate name, which PDF readers show as the tooltip.
- **[FieldType](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-pdf/acroforms-formfield/fieldtype-property/llms-full.txt)** is `Tx` for a text field, `Btn` for a button, `Ch` for a choice field or `Sig` for a signature field.
- **[Bounds](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-pdf/acroforms-formfield/bounds-property/llms-full.txt)** is the rectangle of the field in the document.

`GetAcroFormFields` reads forms filled in and saved with Adobe Acrobat Reader or with Google Chrome since version 85. A user of Chrome saves the filled form with the **Download** button, choosing the version with the changes:

![A PDF form in Google Chrome with the company name filled in and the drop-down list of countries opened.](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-winforms/pdf-form-filled-in-chrome.b3b5e03a.webp)

### Show the Values of a Filled Form

The following code in *Form1.cs* collects the values of a PDF form by field name and shows them after the user picked the file:

```csharp
private Dictionary<string, string> ReadFormValues(string path)
{
    Dictionary<string, string> values = new Dictionary<string, string>();

    foreach (AcroForms.FormField field in Forms.GetAcroFormFields(path))
    {
        switch (field)
        {
            case AcroForms.FormTextField textField:
                values[field.FieldName] = textField.Value;
                break;

            case AcroForms.FormCheckBox checkBox:          // check boxes and radio buttons
                values[field.FieldName] = checkBox.IsChecked ? "true" : "false";
                break;

            case AcroForms.FormChoiceField choiceField:    // combo boxes and list boxes
                values[field.FieldName] = choiceField.Value;
                break;
        }
    }

    return values;
}

private void readFormButton_Click(object sender, EventArgs e)
{
    using (OpenFileDialog dialog = new OpenFileDialog() { Filter = "PDF forms|*.pdf" })
    {
        if (dialog.ShowDialog() != DialogResult.OK)
        {
            return;
        }

        Dictionary<string, string> values;

        try
        {
            values = ReadFormValues(dialog.FileName);
        }
        catch (FilterException exception)
        {
            MessageBox.Show("The form could not be read: " + exception.Reason);
            return;
        }

        if (values.Count == 0)
        {
            MessageBox.Show("The PDF document has no form fields.");
            return;
        }

        MessageBox.Show(string.Join("\n", values.Select(value => value.Key + ": " + value.Value)));
    }
}
```

*Form1.cs* needs these `using` directives:

```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using TXTextControl;
using TXTextControl.DocumentServer.PDF;
using AcroForms = TXTextControl.DocumentServer.PDF.AcroForms;
```

The code works as follows:

- The alias `AcroForms` separates the classes of the PDF from the form fields of the document, because both namespaces have a class named `FormField`.
- The `switch` statement tests `FormCheckBox` for check boxes and radio buttons and the base class `FormChoiceField` for combo boxes and list boxes, because the program needs only their values. To tell the derived classes apart, test `FormRadioButton` before `FormCheckBox` and `FormListBox` before `FormComboBox`.
- The indexer of the dictionary keeps the last value when a name occurs more than once in the array, where `ToDictionary` would throw.
- A file that isn't a readable PDF throws a [FilterException](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/filterexception/llms-full.txt). `GetAcroFormFields` takes no password, so the fields of a PDF that requires a password to open can't be read.

For the form of Getting Started, the message shows lines such as `name: Tim Typer`, `country: Germany` and `newsletter: true`.

### Put the Values Back Into the Form

TX Text Control doesn't write values into an existing PDF. To continue with the values in your application, load your own document of the form, the one the PDF was created from, into `textControl1` and transfer the values into its form fields:

```csharp
private void fillEditorFormButton_Click(object sender, EventArgs e)
{
    Dictionary<string, string> values = ReadFormValues("form-filled.pdf");

    // The main text, headers, footers and text frames
    foreach (IFormattedText textPart in textControl1.TextParts)
    {
        foreach (FormField formField in textPart.FormFields)
        {
            if (string.IsNullOrEmpty(formField.Name) ||
                !values.TryGetValue(formField.Name, out string value) || value == null)
            {
                continue;
            }

            switch (formField)
            {
                case CheckFormField checkFormField:
                    checkFormField.Checked = value == "true";
                    break;

                case SelectionFormField selectionFormField:
                    // -1 selects nothing if the value isn't one of the items
                    selectionFormField.SelectedIndex = Array.IndexOf(selectionFormField.Items, value);
                    break;

                case TextFormField textFormField:
                    textFormField.Text = value;
                    break;
            }
        }
    }
}
```

The code works as follows:

- [TextControl.TextParts](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/textparts-property/llms-full.txt) contains the main text, the headers and footers and the text frames, each with its own [FormFields](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/iformattedtext/formfields-property/llms-full.txt) collection.
- Each form field type takes the value through its own property: [Checked](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/checkformfield/checked-property/llms-full.txt) for check boxes, [SelectedIndex](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/selectionformfield/selectedindex-property/llms-full.txt) of the [Items](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/selectionformfield/items-property/llms-full.txt) for selection fields and [Text](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textfield/text-property/llms-full.txt) for text form fields.
- Date form fields are left out: their value arrives as the text the form displayed. To set one, parse the text with the culture of the form and assign [DateFormField.Date](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/dateformfield/date-property/llms-full.txt).

Saved again as PDF, the document is a new fillable form with the values; flattened first, it is a document with fixed values, as [Exporting Interactive and Flattened Forms](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/pdf/forms/exporting/llms-full.txt) shows. Instead of setting each field, you can also merge the values with `MailMerge` and `FormFieldMergeType.Preselect`, as [Merge Form Fields](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/fields/#merge-form-fields) describes.

### Next Steps

- [Exporting Interactive and Flattened Forms](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/pdf/forms/exporting/llms-full.txt): save the form with fixed values.
- [Creating AcroForms](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/pdf/forms/acroforms/llms-full.txt): create the PDF forms you read.
- The blog article [Export and Import Adobe PDF XFDF XML Files in .NET C#](https://www.textcontrol.com/blog/2025/01/22/export-and-import-adobe-pdf-xfdf-xml-files-in-net-c-sharp/): store the values of a form as XFDF.

---

## Nearby

- **Previous:** [Creating AcroForms](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/pdf/forms/acroforms/llms-full.txt)
- **Next:** [Exporting Interactive and Flattened Forms](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/pdf/forms/exporting/llms-full.txt)
