All docs
V20.1
20.1
19.2
19.1
The page you are viewing does not exist in version 19.1. This link will take you to the root page.
18.2
The page you are viewing does not exist in version 18.2. This link will take you to the root page.
18.1
The page you are viewing does not exist in version 18.1. This link will take you to the root page.
17.2
The page you are viewing does not exist in version 17.2. This link will take you to the root page.

Track Changes

  • 6 minutes to read

The RichEditControl allows you to track changes in a document. You can view, accept or reject revisions made to a document.

dxrichedit-track-changes

The RichEditControl supports Track Changes in the following formats:

  • DOCX;
  • DOC;
  • RTF;
  • WordML;
  • HTML;
  • PDF (export only).

Enable Track Changes in the Document

In Code

Use the following API to enable Track Changes and specify the revision options:

API Description
Document.TrackChanges Provides access to the document's tracking options (DocumentTrackChangesOptions).
DocumentTrackChangesOptions.Enabled Enables tracking in the document. When tracking is enabled, new document modifications are added as revisions.
DocumentTrackChangesOptions.TrackFormatting
DocumentTrackChangesOptions.TrackMoves
Specify whether to track formatting changes (character or paragraph properties' changes) or content movements.

The code sample below shows how to enable Track Changes and change formatting options for the specified range. As a result, a new revision is added to the collection:

NOTE

A complete code sample project is available at How to Manage Tracked Changes in DXRichEdit repository on Github.

DocumentTrackChangesOptions documentTrackChangesOptions = documentProcessor.Document.TrackChanges;
documentTrackChangesOptions.Enabled = true;
documentTrackChangesOptions.TrackFormatting = true;
documentTrackChangesOptions.TrackMoves = true;

//Format the specific phrase in the document:
//This modification is added an a new revision:
DocumentRange[] targetPhrases = documentProcessor.Document.FindAll("We measured hard disk space as a function of USB key space on an IBM PC Junior.", SearchOptions.None);
CharacterProperties characterProperties = documentProcessor.Document.BeginUpdateCharacters(targetPhrases[0]);
characterProperties.FontName = "Arial";
characterProperties.Italic = true;
documentProcessor.Document.EndUpdateCharacters(characterProperties);

From the User Interface

The Review ribbon tab allows users to keep track of changes made in the current document.

The Track Changes drop-down menu allows you to enable track changes and provide a password to prevent users from disabling Track Changes.

IMAGE

Show Revisions from Specific Authors

In Code

The DXRichEditAnnotationOptions class properties allow you to specify the current author and authors whose revisions should be displayed.

richEditControl1.AnnotationOptions.Author = "Anne Dodsworth";

//Disable showing revisions from all authors
richEditControl1.AnnotationOptions.ShowAllAuthors = false;

//Remove authors whose revisions should not be displayed:
richEditControl1.AnnotationOptions.VisibleAuthors.Remove("Ryan Anita W");
richEditControl1.AnnotationOptions.VisibleAuthors.Remove("Michael Suyama");

From the User Interface

Use the Show Markup drop-down menu to select reviewers whose revisions should be displayed.

IMAGE

Change Display Options for Revision

The DXRichEditTrackChangesOptions class properties allows you to specify revision display options for the RichEditControl. You can specify a color and format for each revision type and change the review mode.

Access these properties via the richEditControl.AnnotationOptions.TrackChangesOptions notation.

TIP

Set the TrackChangesOptions.DisplayForReviewMode property to DisplayForReviewMode.NoMarkup to hide changes when the document is printed or exported to PDF.

<dxre:RichEditControl x:Name="richEditControl1" CommandBarStyle="Ribbon">
    <dxre:RichEditControl.AnnotationOptions>
        <dxre:DXRichEditAnnotationOptions ShowAllAuthors="True">
            <dxre:DXRichEditAnnotationOptions.TrackChangesOptions>
                <dxre:DXRichEditTrackChangesOptions DeletedCellColor="Gray"
                                                    InsertionColor="Red"
                                                    DisplayForReviewMode="SimpleMarkup"
                                                    DisplayInsertionStyle="Bold"
                                                    DisplayDeletionStyle="DoubleStrikethrough"/>
            </dxre:DXRichEditAnnotationOptions.TrackChangesOptions>
        </dxre:DXRichEditAnnotationOptions>
    </dxre:RichEditControl.AnnotationOptions>
</dxre:RichEditControl>

From the User Interface

Use the Display for Review drop-down list to specify how to display changes in the document.

IMAGE

The RichEditControl provides the following modes:

  • All Markup - displays revisions in details.

    all-markup

  • Simple Markup - displays revisions indicated by a red line in the margin.

    simple-markup

  • No Markup - displays the document without any visible revisions (as if all revisions are accepted).

    no-markup

Access Revisions

The Document.Revisions property provides access to the read-only collection of document revisions.

Call the RevisionCollection.Get method to retrieve revisions related to a document part (main body, header, footer, and text box). Pass the target SubDocument instance as the method's parameter. The following properties allow you to access a specific document part's SubDocument:

Document Part Property
Main Body RichEditControl.Document
Header or Footer Section.BeginUpdateHeader
Section.BeginUpdateFooter
Text Box TextBox.Document

The RevisionCollection.Get(DocumentRange) method overload allows you to retrieve changes made to a document range.

The code sample below shows how to retrieve revisions made in the first section's header and in the first paragraph:

foreach (Shape shape in documentProcessor.Document.Shapes)
//Get revisions from the header:
SubDocument header = richEditControl.Document.Sections[0].BeginUpdateHeader(HeaderFooterType.First);
var sectionRevisions = richEditControl.Document.Revisions.Get(header);
richEditControl.Document.Sections[0].EndUpdateHeader(header);

//Get revisions from the first paragraph:
Paragraph firstParagraph = richEditControl.Document.Paragraphs[0];
var paragraphRevisions = richEditControl.Document.Revisions.Get(firstParagraph.Range);

Accept and Reject Revisions

In Code

Use the Revision object's properties to obtain the revision's date, author, and type. The Revision.Range property provides access to the document range to which the revision is applied. This property retrieves the range after the revision.

Call the Revision.Accept orRevision.Reject method to accept or reject a specific revision.

Use the RevisionCollection.AcceptAll or RevisionCollection.RejectAll method to manage all revisions in the document or in the specific document part.

The code sample below shows how to reject all revisions on the first page's header:

SubDocument header = documentProcessor.Document.Sections[0].BeginUpdateHeader(HeaderFooterType.First);
documentRevisions.RejectAll(header);
richEditControl.Document.Sections[0].EndUpdateHeader(header);

Pass the Predicate<T> delegate as one of the method's parameter to accept or reject all revisions that meet the criteria.

The code sample below rejects all revisions in the first section from the specific author:

//Reject all revisions in the first section from the specific author:
var sectionRevisions = documentRevisions.Get(documentProcessor.Document.Sections[0].Range).Where(x => x.Author == "Janet Leverling");

foreach (Revision revision in sectionRevisions)
        revision.Reject();

From the User Interface

You can use the buttons on the Changes ribbon group or context menu items to move between revisions, accept or reject changes.

IMAGE

Revision Conflicts

When you move text, change it, and then reject this move, a conflict occurs that fires Document.TrackedMovesConflict and RichEditControl.TrackedMovesConflict events. Handle one of the events to specify the version of the text you want to keep (the TrackedMovesConflictEventArgs.ResolveMode property).

Use the TrackedMovesConflictEventArgs.OriginalLocationRange and TrackedMovesConflictEventArgs.NewLocationRange properties to obtain the original and new location range, and the xref:Revision property to retrieve the revision that fired this event.

The code sample below shows how to handle the TrackedMovesConflict event:

private void WordProcessor_TrackedMovesConflict(object sender, TrackedMovesConflictEventArgs e)
{
  //Compare the length of the original and new location ranges
  //Keep text from the location whose range is the smallest
  e.ResolveMode = (e.OriginalLocationRange.Length <= e.NewLocationRange.Length) ? TrackedMovesConflictResolveMode.KeepOriginalLocationText : TrackedMovesConflictResolveMode.KeepNewLocationText;
}

Limitations

Track Changes has the following limitations:

  • Revisions in OpenDocument (.odt) format are not supported.
  • No Original mode to view changes.
  • No user interface elements to specify Track Changes display options.
  • The Reviewing Pane does not display revisions.
  • Revisions are not displayed in balloons that appear in document margin.