# Comments

> Work with MS Word compatible comments in a WPF TextControl: add comments and replies in code, list and remove them, set CommentHighlightMode and handle events.

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

---

Reviewers leave notes on a draft without touching its wording, and the WPF `TextControl` stores such notes as comments compatible with MS Word. Users work with them through the context menu, the **Proofing** tab and a sidebar; your code reads, adds, answers and removes them through the `CommentCollection` and learns about every change from events.

The code samples use a `TextControl` named `textControl1` in *MainWindow.xaml*, as in [Create Your First WPF Application](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/getting-started/document-editor/first-application/llms-full.txt), with the button handlers in *MainWindow.xaml.cs*.

### How Comments Work

Each comment is a *commented text*: a range of the document plus the comment string. On the screen, commented text is highlighted in a color that depends on its author, red for the current user. The author is the user who was current when the comment was added, the first name in [UserNames](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/usernames-property/llms-full.txt), or an unknown user if the list is empty.

A comment can have *replies* from other users. They refer to the same range of text. When a comment is removed, its replies go with it, while the commented text stays in the document.

The TX Text Control format (TX), RTF, DOC and DOCX keep comments when a document is saved and restore them when it is loaded, including comments written in MS Word.

### Comment Text as a User

With text selected, the user adds a comment from the context menu or with **Add Comment** on the **Proofing** tab. The comment goes into the document once the user closes the input box with a mouse click or the Enter key. Right-clicking a comment offers to edit it, delete it or reply to it. A Comments sidebar lists the comments of the document:

![The TX Text Control Words sample for WPF with a comment balloon above the heading Protected Document and the Comments sidebar showing the comment, its author John and the date.](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-wpf/comments-sidebar.334ae244.webp)

The **Comments** button of the [RibbonProofingTab](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/ribbonproofingtab/llms-full.txt) opens that sidebar when its [CommentsSidebar](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/ribbonproofingtab/commentssidebar-property/llms-full.txt) property holds the name of a sidebar in the window; see [Sidebar and Panels](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/ribbon-ui/sidebar/llms-full.txt). An application without a ribbon shows the same list in the modeless [CommentsDialog](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/commentsdialog/llms-full.txt) window of the `TXTextControl.WPF` namespace:

```csharp
private void CommentsDialogButton_Click(object sender, RoutedEventArgs e)
{
    TXTextControl.WPF.CommentsDialog dialog = new TXTextControl.WPF.CommentsDialog(textControl1);
    dialog.Show();
}
```

### Add Comments in Code

The [Comments](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/comments-property/llms-full.txt) property returns a [CommentCollection](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/commentcollection/llms-full.txt) with the comments of the text part that has the input focus. [Add](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/commentcollection/add-method/llms-full.txt) inserts a comment given as a [CommentedText](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/commentedtext/llms-full.txt) object, or, without a parameter, opens the input box so that the user types the comment. `CommentCollection` and `CommentedText` are classes of the `TXTextControl` namespace:

```csharp
using System.Windows;
using TXTextControl;

// ...

private void AddCommentButton_Click(object sender, RoutedEventArgs 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, RoutedEventArgs e)
{
    // Comment the first 20 characters; the start is one-based
    textControl1.Comments.Add(new CommentedText("Shorten the heading.", 1, 20));
}
```

What the code does:

- A `CommentedText` created with the comment string only refers to the current selection.
- `Add` reports the outcome as a value of [CommentCollection.AddResult](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/commentcollection/addresult-enumeration/llms-full.txt). `Successful` means the comment was inserted; `NoSelection` and `SelectionTooComplex` mean there was no selection or no continuous one.
- The constructor with a start and a length comments a range without selecting it. The first character has the position 1.

### Read and Answer Comments

Enumerating the collection returns all comments and replies. [GetItem](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/commentcollection/getitem-method/llms-full.txt) returns the comment at the input position, and `GetItem(true)` or `GetItem(false)` the next or previous one; each returns `null` if there is none:

```csharp
private void ListCommentsButton_Click(object sender, RoutedEventArgs 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, RoutedEventArgs e)
{
    CommentedText comment = textControl1.Comments.GetItem();

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

| Member | Value |
|---|---|
| [Text](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/commentedtext/text-property/llms-full.txt) | The commented text |
| [Comment](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/commentedtext/comment-property/llms-full.txt) | The comment itself; setting it changes the comment |
| [UserName](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/commentedtext/username-property/llms-full.txt), [CreationTime](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/commentedtext/creationtime-property/llms-full.txt) | The author and the time of the comment in UTC |
| [Replies](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/commentedtext/replies-property/llms-full.txt) | The replies, or `null` without replies |
| [RepliedComment](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/commentedtext/repliedcomment-property/llms-full.txt) | For a reply, the comment it answers |

A reply is a `CommentedText` created with the answered comment as its second parameter, and `Add` inserts it like any other comment.

### Edit, Remove and Navigate

- [EditComment](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/commentedtext/editcomment-method/llms-full.txt) opens the input box with the comment, and [ReplyToComment](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/commentedtext/replytocomment-method/llms-full.txt) an input box for a reply. `ReplyToComment` returns `false` for a reply.
- [ScrollTo](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/commentedtext/scrollto-method/llms-full.txt) moves the input position to the commented text and scrolls it into view, and [Select](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/commentedtext/select-method/llms-full.txt) selects it.
- [Start](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/commentedtext/start-property/llms-full.txt) and [Length](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/commentedtext/length-property/llms-full.txt) give the one-based position and the length of the commented text.
- [ID](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/commentedtext/id-property/llms-full.txt) stores an identifier of your own, such as the key of the comment in a database.

[CommentCollection.Remove](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/commentcollection/remove-method/llms-full.txt) deletes a comment and leaves its text in place:

```csharp
private void DeleteCommentButton_Click(object sender, RoutedEventArgs 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-wpf/reference/txtextcontrol-wpf/textcontrol/commenthighlightmode-property/llms-full.txt) decides when commented text is highlighted. It can be set in XAML, for example `CommentHighlightMode="Always"`:

| Value | Commented text is highlighted |
|---|---|
| `Activated` | While it contains the input position (default) |
| `Always` | Always |
| `Never` | Never |

The [HighlightMode](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/commentedtext/highlightmode-property/llms-full.txt) and [HighlightColor](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/commentedtext/highlightcolor-property/llms-full.txt) of a single comment override the setting for that comment. `HighlightColor` is a `System.Drawing.Color`. A comment whose [Active](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/commentedtext/active-property/llms-full.txt) property is `false` isn't highlighted, and `GetItem` doesn't return it.

### React to Comments

Six events report comments, each with [CommentEventArgs](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/commenteventargs/llms-full.txt) whose [CommentedText](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/commenteventargs/commentedtext-property/llms-full.txt) is the comment concerned:

- [CommentCreated](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/commentcreated-event/llms-full.txt) and [CommentDeleted](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/commentdeleted-event/llms-full.txt) when a comment has been added or removed.
- [CommentChanged](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/commentchanged-event/llms-full.txt) when its text has been changed.
- [CommentStateChanged](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/commentstatechanged-event/llms-full.txt) when it has become active or inactive.
- [CommentedTextEntered](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/commentedtextentered-event/llms-full.txt) and [CommentedTextLeft](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/commentedtextleft-event/llms-full.txt) when the input position has moved into or out of commented text.

Connect a handler as an attribute of the control in *MainWindow.xaml*:

```xml
<WPF:TextControl x:Name="textControl1"
                CommentedTextEntered="TextControl1_CommentedTextEntered" />
```

The handler shows the comment at the input position in the title of the window:

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

Comments of stored documents, for example for an import into a database, are read without the editor through the `Comments` collection of a `ServerTextControl`. See [Comments and Tracked Changes](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-processing/comments-changes/llms-full.txt) and 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-wpf/document-editor/track-changes/llms-full.txt): record insertions and deletions and accept or reject them.
- [Document Protection and Editable Regions](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/protection/llms-full.txt): user names and protected documents.
- [Sidebar and Panels](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/ribbon-ui/sidebar/llms-full.txt): add the Comments panel to the window.
- [Built-in Dialog Boxes](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/ribbon-ui/dialog-boxes/llms-full.txt): the other dialog windows of the editor.

---

## Nearby

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