Track Changes

GemBox.Document has support for working with changes (revisions) in a document. You can accept or reject a revision, create a new revision or get the revision information.

The following example shows how you can accept or reject all revisions in the document.

Word document with accepted changes
Screenshot of Word file with accepted changes
using System;
using GemBox.Document;

class Program
{
    static void Main()
    {
        // If using Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY");

        var document = DocumentModel.Load("%#Revisions.docx%");
        var acceptRevisions = %AcceptRevisions%;

        if (acceptRevisions)
            document.Revisions.AcceptAll();
        else
            document.Revisions.RejectAll();

        document.Save("Revised Document.%OutputFileType%");
    }
}
Imports System
Imports GemBox.Document

Module Program

    Sub Main()

        ' If using Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY")

        Dim document = DocumentModel.Load("%#Revisions.docx%")
        Dim acceptRevisions = %AcceptRevisions%

        If acceptRevisions Then
            document.Revisions.AcceptAll()
        Else
            document.Revisions.RejectAll()
        End If

        document.Save("Revised Document.%OutputFileType%")
    End Sub
End Module

Accepting/rejecting individual revisions

Besides accepting or rejecting all revisions in the document, you can access individual revisions and accept or reject them based on their properties.

The following example shows simple decisions when accepting and rejecting revisions.

using System;
using GemBox.Document;
using GemBox.Document.Tracking;

class Program
{
    static void Main()
    {
        // If using Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY");

        var document = DocumentModel.Load("%#Revisions.docx%");

        // Iterate through all runs in the document.
        foreach (Run run in document.GetChildElements(true, ElementType.Run))
        {
            // Reject revision of the character format.
            if (run.CharacterFormatRevision != null)
                run.CharacterFormatRevision.Reject();

            // Reject deletion of a run.
            if (run.Revision?.RevisionType == RevisionType.Delete)
                run.Revision.Reject();
        }

        // Iterate through all remaining revisions in the document.
        foreach (var revision in document.Revisions)
        {
            // Accept only revisions from GemBox that were added last month.
            if (revision.Author == "GemBox" && revision.Date > DateTime.Now.AddMonths(-1))
                revision.Accept();
        }

        document.Save("Processed Revisions.%OutputFileType%");
    }
}
Imports System
Imports GemBox.Document
Imports GemBox.Document.Tracking

Module Program

    Sub Main()

        ' If using Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY")

        Dim document = DocumentModel.Load("%#Revisions.docx%")

        ' Iterate through all runs in the document.
        For Each run As Run in document.GetChildElements(true, ElementType.Run)
            ' Reject revision of the character format.
            If run.CharacterFormatRevision IsNot Nothing
                run.CharacterFormatRevision.Reject()
            End If

            ' Reject deletion of a run.
            If run.Revision?.RevisionType = RevisionType.Delete Then
                run.Revision.Reject()
            End If
        Next

        ' Iterate through all remaining revisions in the document.
        For Each revision in document.Revisions
            ' Accept only revisions from GemBox that were added last month.
            If revision.Author = "GemBox" And revision.Date > DateTime.Now.AddMonths(-1) Then
                revision.Accept()
            End If
        Next

        document.Save("Processed Revisions.%OutputFileType%")

    End Sub
End Module

Creating revisions

Even though GemBox.Document doesn't have support for tracking changes automatically, it has an API which allows you to create revisions programmatically. See the Tracking namespace to see which members can be used in the revision API.

The following example shows how you can update a document and track the changes.

Word document with added revisions
Screenshot of Word file with added revisions
using System;
using GemBox.Document;
using GemBox.Document.Tables;
using GemBox.Document.Tracking;

class Program
{
    static void Main()
    {
        // If using Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY");

        var document = DocumentModel.Load("%#NoRevisions.docx%");
        var section = document.Sections[0];

        var paragraph1 = section.Blocks.Cast<Paragraph>(0);
        var run1 = paragraph1.Inlines.Cast<Run>(0);

        // 1. Changing the formatting of the run.
        var characterFormatRevision = new CharacterFormatRevision(document)
        {
            Author = "GemBox",
            Date = DateTime.Now
        };
        // CharacterFormatRevision.CharacterFormat holds the format which was used before the revision was applied.
        characterFormatRevision.CharacterFormat = run1.CharacterFormat.Clone();
        run1.CharacterFormatRevision = characterFormatRevision;
        // Changing the format.
        run1.CharacterFormat.UnderlineStyle = UnderlineType.Double;

        // 2. Removing the run.
        var run2 = paragraph1.Inlines.Cast<Run>(1);
        // Mark run as deleted.
        run2.Revision = new Revision(RevisionType.Delete) { Author = "GemBox" };

        // 3. Inserting a run.
        var run3 = new Run(document, "Run3");
        // Mark run as inserted.
        run3.Revision = new Revision(RevisionType.Insert) { Author = "GemBox" };
        paragraph1.Inlines.Add(run3);

        // 4. Joining paragraphs.
        var paragraph2 = section.Blocks.Cast<Paragraph>(1);
        // Marking paragraph as deleted doesn't remove the paragraph content, it joins it with the following paragraph.
        paragraph2.Revision = new Revision(RevisionType.Delete) { Author = "GemBox" };

        var table = section.Blocks.Cast<Table>(3);

        // 5. Removing a table row.
        var row2 = table.Rows[1];
        // Mark row as deleted.
        row2.Revision = new Revision(RevisionType.Delete) { Author = "GemBox" };

        // 6. Adding a new table row.
        var newRow = new TableRow(document,
            new TableCell(document, new Paragraph(document, "new row")),
            new TableCell(document));
        // Mark row as inserted.
        newRow.Revision = new Revision(RevisionType.Insert) { Author = "GemBox" };
        table.Rows.Add(newRow);

        document.Save("Added Revisions.%OutputFileType%");
    }
}
Imports System
Imports GemBox.Document
Imports GemBox.Document.Tables
Imports GemBox.Document.Tracking

Module Program

    Sub Main()

        ' If using Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY")

        Dim document = DocumentModel.Load("%#NoRevisions.docx%")
        Dim section = document.Sections(0)

        Dim paragraph1 = section.Blocks.Cast(Of Paragraph)(0)
        Dim run1 = paragraph1.Inlines.Cast(Of Run)(0)

        ' 1. Changing the formatting of the run.
        Dim characterFormatRevision = New CharacterFormatRevision(document) With
        {
            .Author = "GemBox",
            .Date = System.DateTime.Now
        }
        ' CharacterFormatRevision.CharacterFormat holds the format which was used before the revision was applied.
        characterFormatRevision.CharacterFormat = run1.CharacterFormat.Clone()
        run1.CharacterFormatRevision = characterFormatRevision
        ' Changing the format.
        run1.CharacterFormat.UnderlineStyle = UnderlineType.Double

        ' 2. Removing the run.
        Dim run2 = paragraph1.Inlines.Cast(Of Run)(1)
        ' Mark run as deleted.
        run2.Revision = New Revision(RevisionType.Delete) With {.Author = "GemBox"}

        ' 3. Inserting a run.
        Dim run3 = New Run(document, "Run3")
        ' Mark run as inserted.
        run3.Revision = New Revision(RevisionType.Insert) With {.Author = "GemBox"}
        paragraph1.Inlines.Add(run3)

        ' 4. Joining paragraphs.
        Dim paragraph2 = section.Blocks.Cast(Of Paragraph)(1)
        ' Marking paragraph as deleted doesn't remove the paragraph content, it joins it with the following paragraph.
        paragraph2.Revision = New Revision(RevisionType.Delete) With {.Author = "GemBox"}
        Dim table = section.Blocks.Cast(Of Table)(3)

        ' 5. Removing a table row.
        Dim row2 = table.Rows(1)
        ' Mark row as deleted.
        row2.Revision = New Revision(RevisionType.Delete) With {.Author = "GemBox"}

        ' 6. Adding a new table row.
        Dim newRow = New TableRow(document,
            New TableCell(document, New Paragraph(document, "new row")),
            New TableCell(document))
        ' Mark row as inserted.
        newRow.Revision = New Revision(RevisionType.Insert) With {.Author = "GemBox"}
        table.Rows.Add(newRow)

        document.Save("Added Revisions.%OutputFileType%")

    End Sub
End Module

Want more?

Next example GitHub

Check the next example or select an example from the menu. You can also download our examples from the GitHub.


Like it?

Download Buy

If you want to try the GemBox.Document yourself, you can download the free version. It delivers the same performance and set of features as the professional version, but with some operations limited. To remove the limitation, you need to purchase a license.