# Comments

> Add, answer, edit and remove comments in a Windows Forms TextControl with CommentCollection and CommentedText, the Comments sidebar, CommentsDialog and events.

- **Product:** TX Text Control .NET for Windows Forms
- **Section:** Documentation
- **Kind:** Topic
- **Path:** TX Text Control .NET for Windows Forms > Document Editor > Comments
- **3441 words**
- **Web URL:** https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/comments/
- **LLMs URL:** https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/comments/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/comments/llms-full.txt

---

A comment attaches a note to a piece of text without changing the text itself, the way reviewers annotate a draft in MS Word. Users of a `TextControl` add, answer, edit and delete comments with the context menu, the ribbon and a sidebar, and your code does the same with the `CommentCollection`. Read on for both, and for the events that tell your application when comments come and go.

The code below belongs in *Form1.cs* of a Windows Forms application whose editor is named `textControl1`, as in [Create Your First Windows Forms Application](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/getting-started/document-editor/first-application/llms-full.txt).

### How Comments Work

A comment consists of the commented text and the comment string, together a *commented text*. The editor highlights commented text in a color that depends on the author; the current user's comments are red. A comment belongs to the current user when it is added, which is the first name of [UserNames](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/usernames-property/llms-full.txt). With an empty list, the author is unknown.

Comments can have *replies*. A reply refers to the same text but can come from another user at another time. Removing a comment also removes its replies, and never the commented text.

Comments are saved with the document and loaded again in the TX Text Control format (TX), RTF, DOC and DOCX, so comments made in MS Word show up in the editor and the other way around.

### Comment Text as a User

Users select text and add a comment from the context menu or with **Add Comment** on the **Proofing** tab of the ribbon. An input box opens beside the text; the comment is added when the user closes it with a mouse click or the Enter key. The context menu of a comment has entries to edit, delete and reply to it.

The Comments sidebar lists all comments with their author and time:

![TX Text Control Words with a comment balloon above the heading Protected Document and the Comments sidebar on the right showing the comment with the user name John and a date.](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-winforms/comments-sidebar.2d3d5255.webp)

To open it from the **Comments** button of the tab, connect a sidebar with the [CommentsSidebar](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-windows-forms-ribbon/ribbonproofingtab/commentssidebar-property/llms-full.txt) property of the [RibbonProofingTab](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-windows-forms-ribbon/ribbonproofingtab/llms-full.txt); [Sidebar and Panels](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/ribbon-ui/sidebar/llms-full.txt) shows how. Without a ribbon, the [CommentsDialog](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/commentsdialog/llms-full.txt) shows the same list in a modeless dialog box:

```csharp
private void commentsDialogButton_Click(object sender, EventArgs e)
{
    CommentsDialog dialog = new CommentsDialog(textControl1);
    dialog.Show();
}
```

### Add Comments in Code

[Comments](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/comments-property/llms-full.txt) returns the [CommentCollection](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/commentcollection/llms-full.txt) of the text part with the input focus. Its [Add](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/commentcollection/add-method/llms-full.txt) method has two overloads: without a parameter, it opens the input box for the selected text, and with a [CommentedText](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/commentedtext/llms-full.txt), it inserts a prepared comment:

```csharp
private void addCommentButton_Click(object sender, EventArgs e)
{
    // Comment the selected text
    CommentCollection.AddResult result =
        textControl1.Comments.Add(new CommentedText("Please check this figure."));

    if (result == CommentCollection.AddResult.NoSelection)
    {
        MessageBox.Show("Select the text you want to comment on.");
    }
}

private void commentHeadingButton_Click(object sender, EventArgs e)
{
    // Comment the first 20 characters; the start is one-based
    textControl1.Comments.Add(new CommentedText("Shorten the heading.", 1, 20));
}
```

The code works as follows:

- `new CommentedText("...")` comments the current selection. `Add` returns a value of [CommentCollection.AddResult](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/commentcollection/addresult-enumeration/llms-full.txt): `Successful`, or a reason such as `NoSelection`, `PositionInvalid` or `SelectionTooComplex`, when the selection isn't one continuous range of text.
- `new CommentedText(comment, start, length)` comments a range without selecting it. `start` is one-based: 1 is the first character.
- `textControl1.Comments.Add()` without a parameter opens the input box for the user, as the ribbon button does.

### Read and Answer Comments

The collection enumerates all comments and replies of the text part. [GetItem](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/commentcollection/getitem-method/llms-full.txt) returns the comment at the input position, `GetItem(true)` the next one and `GetItem(false)` the previous one, or `null` if there is none. The following code lists the comments with their replies and answers the comment at the input position:

```csharp
private void listCommentsButton_Click(object sender, EventArgs e)
{
    System.Text.StringBuilder report = new System.Text.StringBuilder();

    foreach (CommentedText comment in textControl1.Comments)
    {
        // Replies are listed below the comment they answer
        if (comment.RepliedComment != null)
        {
            continue;
        }

        report.AppendLine($"\"{comment.Text}\": {comment.Comment} " +
            $"({comment.UserName}, {comment.CreationTime.ToLocalTime()})");

        foreach (CommentedText reply in comment.Replies ?? new CommentedText[0])
        {
            report.AppendLine($"    {reply.UserName}: {reply.Comment}");
        }
    }

    MessageBox.Show(report.ToString(), "Comments");
}

private void replyButton_Click(object sender, EventArgs e)
{
    CommentedText comment = textControl1.Comments.GetItem();

    if (comment != null)
    {
        textControl1.Comments.Add(new CommentedText("Done.", comment));
    }
}
```

- [Text](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/commentedtext/text-property/llms-full.txt) is the commented text and [Comment](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/commentedtext/comment-property/llms-full.txt) the comment, which can also be set.
- [UserName](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/commentedtext/username-property/llms-full.txt) is the author and [CreationTime](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/commentedtext/creationtime-property/llms-full.txt) the time in UTC.
- [Replies](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/commentedtext/replies-property/llms-full.txt) returns the replies, or `null` if there are none, and [RepliedComment](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/commentedtext/repliedcomment-property/llms-full.txt) the comment a reply answers.
- `new CommentedText(comment, repliedComment)` creates a reply, which `Add` inserts.

### Edit, Remove and Navigate

A `CommentedText` has methods for the user interface and for its position:

| Member | Purpose |
|---|---|
| [EditComment](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/commentedtext/editcomment-method/llms-full.txt) | Opens the input box to edit the comment |
| [ReplyToComment](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/commentedtext/replytocomment-method/llms-full.txt) | Opens the input box for a reply; returns `false` for a comment that is itself a reply |
| [ScrollTo](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/commentedtext/scrollto-method/llms-full.txt) | Moves the input position to the commented text and scrolls it into view |
| [Select](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/commentedtext/select-method/llms-full.txt) | Selects the commented text |
| [Start](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/commentedtext/start-property/llms-full.txt), [Length](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/commentedtext/length-property/llms-full.txt) | The one-based position and the length of the commented text |
| [ID](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/commentedtext/id-property/llms-full.txt) | An identifier of your own, for example the key of the comment in your database |

[CommentCollection.Remove](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/commentcollection/remove-method/llms-full.txt) removes a comment, and the text stays:

```csharp
private void deleteCommentButton_Click(object sender, EventArgs e)
{
    CommentedText comment = textControl1.Comments.GetItem();

    if (comment != null)
    {
        textControl1.Comments.Remove(comment);
    }
}
```

### Change the Highlighting

[CommentHighlightMode](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/commenthighlightmode-property/llms-full.txt) of the `TextControl` decides when commented text is highlighted:

- `HighlightMode.Activated`, the default, highlights a comment while the input position is in it.
- `HighlightMode.Always` highlights all comments.
- `HighlightMode.Never` highlights none.

A single comment can differ from this setting with its own [HighlightMode](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/commentedtext/highlightmode-property/llms-full.txt) and [HighlightColor](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/commentedtext/highlightcolor-property/llms-full.txt). [Active](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/commentedtext/active-property/llms-full.txt) set to `false` deactivates a comment: it is no longer highlighted, and `GetItem` skips it.

### React to Comments

The following events inform your application about comments. Each handler receives [CommentEventArgs](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/commenteventargs/llms-full.txt), whose [CommentedText](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/commenteventargs/commentedtext-property/llms-full.txt) is the comment:

| Event | Occurs when |
|---|---|
| [CommentCreated](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/commentcreated-event/llms-full.txt) | A piece of text has been commented |
| [CommentDeleted](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/commentdeleted-event/llms-full.txt) | A comment has been removed |
| [CommentChanged](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/commentchanged-event/llms-full.txt) | The text of a comment has been changed |
| [CommentStateChanged](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/commentstatechanged-event/llms-full.txt) | A comment has become active or inactive |
| [CommentedTextEntered](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/commentedtextentered-event/llms-full.txt), [CommentedTextLeft](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/commentedtextleft-event/llms-full.txt) | The input position has moved into or out of commented text |

The following handler shows the comment at the input position in the title bar of the form. Connect it on the **Events** page of the **Properties** window, or with `textControl1.CommentedTextEntered += textControl1_CommentedTextEntered;` in the constructor:

```csharp
private void textControl1_CommentedTextEntered(object sender, CommentEventArgs e)
{
    Text = $"{e.CommentedText.UserName}: {e.CommentedText.Comment}";
}
```

To remove the comments of every text part before a document is sent, see [Comments and Tracked Changes](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-processing/comments-changes/llms-full.txt). To read the comments of stored documents without the editor, for example to import them into a database, use the `Comments` collection of a `ServerTextControl`, as shown in the blog article [Extracting Comments from DOCX Files in .NET C#](https://www.textcontrol.com/blog/2025/01/17/extracting-comments-from-docx-files-in-net-csharp/).

### Next Steps

- [Track Changes](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/track-changes/llms-full.txt): record and review insertions and deletions.
- [Document Protection and Editable Regions](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/protection/llms-full.txt): the user names that also decide who may edit which region.
- [Sidebar and Panels](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/ribbon-ui/sidebar/llms-full.txt): the Comments panel beside the editor.
- [Built-in Dialog Boxes](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/ribbon-ui/dialog-boxes/llms-full.txt): the other dialog boxes of the editor.

---

## Nearby

- **Previous:** [Track Changes](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/track-changes/llms-full.txt)
- **Next:** [Document Protection and Editable Regions](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/protection/llms-full.txt)
