TX Text Control .NET for Windows Forms

Footnotes

Topic

Reports, contracts and academic texts cite their sources in footnotes. In a Windows Forms application, users insert and edit footnotes with the ribbon, and your code adds, numbers, finds and removes them through the Footnotes collection of the TextControl.

The examples extend the application of Create Your First Windows Forms Application: a TextControl named textControl1 on Form1, with buttons whose Click handlers you create by double-clicking them in the designer. Footnotes were introduced in version 32.0 and are part of the Enterprise edition; see Editions and Feature Availability.

How Footnotes Work

A footnote adds an explanation, a comment or a source to a place in the text without interrupting it. It has two parts:

  • The reference mark, a number at the position in the text that the footnote belongs to.
  • The footnote at the bottom of the same page. It starts with a footnote mark, which shows the same number, followed by the footnote text.

TX Text Control numbers all footnotes from the beginning to the end of the document, starting with a start number and in one number format for the whole document. When you insert a footnote in front of existing ones, the following footnotes are renumbered. The footnote text can use every formatting attribute and can contain tables and images.

Footnotes can be inserted in the main text only, not in headers, footers or text frames. They are saved in the TX Text Control format (.tx), in RTF and in the Word formats DOC and DOCX.

The classes involved are Footnote for a single footnote and FootnoteCollection, which the TextControl.Footnotes property returns. The diagram shows them with their members and events:

Class diagram of the footnote API: the Footnotes property and footnote events of TextControl, FootnoteCollection, Footnote, FootnoteEventArgs, FootnoteSection and FootnoteText.

Insert Footnotes With the Ribbon

The References tab of the ribbon, the class RibbonReferencesTab, has a Footnotes group. Its buttons insert a footnote at the input position, delete and edit the current footnote, move to the previous or next footnote and highlight all reference and footnote marks. Two more items set the start number and the number format of all footnotes.

To add the tab, select the ribbon in the designer, click its smart tag and click Add a RibbonReferencesTab, as described in Create Your First Windows Forms Application. The tab works with the TextControl that is connected to the ribbon. Built-in Ribbon Tabs describes all tabs.

Insert a Footnote in Code

Add a button named insertFootnoteButton and double-click it. The handler inserts a footnote at the input position and moves the input position into the new footnote text, so that the user can go on typing there:

private void insertFootnoteButton_Click(object sender, EventArgs e)
{
    // The footnote text, a name and an ID; 0 means no ID
    Footnote footnote = new Footnote("Source: annual report 2025, page 12.", "source", 0);

    // true: move the input position into the footnote text
    if (!textControl1.Footnotes.Add(footnote, true))
    {
        MessageBox.Show("A footnote can't be inserted at this position.");
    }
}

Form1.cs needs using TXTextControl; at the top.

The code works as follows:

  • The Footnote constructor takes the text of the footnote. The second overload adds a name and an ID of your choice, which your code uses to find the footnote later. An empty name or an ID of 0 means none.
  • FootnoteCollection.Add inserts the reference mark at the input position and the footnote at the bottom of the page. With true as the second parameter, the input position is set in the footnote text at the bottom of the page. Add returns false if the footnote can't be inserted, for example in a header.

Place the cursor behind a word and click the button: a number appears at the cursor, the footnote with the same number appears at the bottom of the page, and the cursor jumps into it.

Footnote.Edit moves the input position to the end of the text of an existing footnote, so that it can be edited or formatted like any other text, as described in Text and Paragraph Formatting.

Set the Number Format and Start Number

The numbering belongs to the collection and applies to all footnotes. The following handler of the form's Load event numbers them with small Roman numbers and highlights all marks:

private void Form1_Load(object sender, EventArgs e)
{
    // Number all footnotes i, ii, iii and highlight their marks
    textControl1.Footnotes.NumberFormat = NumberFormat.SmallRomanNumbers;
    textControl1.Footnotes.StartNumber = 1;
    textControl1.Footnotes.HighlightMode = HighlightMode.Always;
}

Connect it in the constructor of the form with Load += Form1_Load;, as in Create Your First Windows Forms Application.

  • NumberFormat takes a value of NumberFormat: ArabicNumbers (1, 2, 3), Letters (a, b, c), CapitalLetters (A, B, C), RomanNumbers (I, II, III) or SmallRomanNumbers (i, ii, iii).
  • StartNumber sets the number of the first footnote, for example when a document continues the numbering of another one.
  • HighlightMode highlights all reference and footnote marks: Always, Never, which is the default, or Activated for the marks that contain the input position. A single footnote overrides it with Footnote.HighlightMode and HighlightColor.

Find, List and Remove Footnotes

The following handlers list all footnotes, move to the next one and remove the footnote named "source":

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

    foreach (Footnote footnote in textControl1.Footnotes)
    {
        // Text begins with the footnote mark
        list.AppendLine(footnote.Number + " (" + footnote.Name + "): " + footnote.Text);
    }

    MessageBox.Show(list.ToString(), textControl1.Footnotes.Count + " footnotes");
}

private void nextFootnoteButton_Click(object sender, EventArgs e)
{
    // true: the next footnote after the input position, false: the previous one
    Footnote footnote = textControl1.Footnotes.GetItem(true);
    footnote?.ScrollTo();
}

private void removeFootnoteButton_Click(object sender, EventArgs e)
{
    Footnote footnote = textControl1.Footnotes.GetItem("source");

    if (footnote != null)
    {
        textControl1.Footnotes.Remove(footnote);
    }
}

StringBuilder needs using System.Text;.

  • Number is the position of the footnote in the text flow, starting with 1. The collection's indexer takes this number as well: textControl1.Footnotes[1] is the first footnote.
  • Text returns the footnote text as plain text, including the footnote mark in front of it. Footnote.Save saves the text in a format such as HTML or RTF instead.
  • GetItem has four overloads: without a parameter it returns the footnote at the input position, with true or false the next or previous footnote, and with a number or a string the footnote with that ID or name. It returns null if there is none.
  • ScrollTo moves the input position to the footnote mark and scrolls it into view.
  • Remove deletes the reference mark and the footnote. The following footnotes are renumbered.

Name, ID and Reference Mark of a Footnote

The name and the ID passed to the constructor are properties of the footnote as well, which your code can read and change later. Name is a string, empty for a footnote without a name, and ID a number of your choice starting at 1, where 0 means none. Two read-only properties locate the reference mark in the text: ReferenceMarkStart is the one-based index of its first character and ReferenceMarkLength the number of its characters.

The following handlers select the reference mark of the footnote named "source" in the text, and move to the footnote at the input position, with its footnote mark at the top of the visible part:

private void selectReferenceMarkButton_Click(object sender, EventArgs e)
{
    Footnote footnote = textControl1.Footnotes.GetItem("source");

    if (footnote != null)
    {
        // ReferenceMarkStart is one-based, Select expects a zero-based position
        textControl1.Select(footnote.ReferenceMarkStart - 1, footnote.ReferenceMarkLength);
    }
}

private void showFootnoteButton_Click(object sender, EventArgs e)
{
    // The footnote at the input position, or null
    Footnote footnote = textControl1.Footnotes.GetItem();

    // Move to the footnote mark and scroll it to the top
    footnote?.ScrollTo(InputPosition.ScrollPosition.Top);
}

TextControl.Select sets the start and length of the selection. ScrollTo() without a parameter chooses the scroll position itself and returns true if the document was scrolled; the overload with an InputPosition.ScrollPosition value (Left, Top, Right or Bottom) places the footnote mark at that side of the visible part. Both overloads move the input position to the footnote mark.

The static Footnote.DefaultHighlightColor returns the default highlight color of the reference and footnote marks, for example to reset a footnote's HighlightColor: footnote.HighlightColor = Footnote.DefaultHighlightColor;.

React to Footnote Events

TextControl raises six footnote events. Their handlers receive a FootnoteEventArgs, whose Footnote property is the footnote concerned:

EventOccurs when
FootnoteCreatedA footnote has been inserted
FootnoteDeletedA footnote has been deleted
FootnoteReferenceMarkEnteredThe input position moves onto a reference mark
FootnoteReferenceMarkLeftThe input position leaves a reference mark
FootnoteSectionActivatedThe footnote text at the bottom of a page gets the input position
FootnoteSectionDeactivatedThe footnote text loses the input position

The following handler shows the text of a footnote in the title bar of the form while the input position is on its reference mark:

public Form1()
{
    InitializeComponent();
    textControl1.FootnoteReferenceMarkEntered += textControl1_FootnoteReferenceMarkEntered;
}

private void textControl1_FootnoteReferenceMarkEntered(object sender, FootnoteEventArgs e)
{
    Text = "Footnote " + e.Footnote.Number + ": " + e.Footnote.Text;
}

A ServerTextControl, which processes documents without a user interface, has the Footnotes collection as well and raises FootnoteCreated and FootnoteDeleted with the same FootnoteEventArgs. The other four events concern the input position and exist only in the TextControl.

Events lists all events of the TextControl.

Next Steps