In a previous post I talked about "Track Changes" and how its behavior might affect your application in ways you did not expect. Implementing a sophisticated piece of logic in VSTO 2005 is hard enough without complicated things further having to cater for "Track Changes", so you might have to make the decision that some of your logic will not support this feature.

Not supporting "Track Changes" is quite simple, if the user has turned it on you turn it off. What you will probably want to do though is turn it back on after you have finished what you were doing so that the user does not complain. Additionally, you want to cater for scenarios were you re-use a piece of code that does not support "Track Changes" (and therefore disables it), but you do not want to re-enable it until your calling code has finished what it was doing.

The following code is an implementation of a solution that takes all of the above into consideration:

public static class TrackChangesManager

{

    ///

    ///     The original value of TrackRevisions.

    ///

    private static bool trackRevisions;

 

    ///

    ///     The number of times that TrackRevisions has been

    ///     disabled without restoring it.

    ///

    ///

    ///     This counter is being used to allow for the nesting

    ///     of RememberAndDisableTrackRevisionsSetting

    ///     and RestoreTrackRevisionsSetting calls.

    ///

    private static int trackRevisionsDisabledCounter = 0;

 

    ///

    ///     Sets the TrackRevisions property of the

    ///     document to false, but remembers its original value.

    ///

    public static void RememberAndDisableTrackRevisionsSetting()

    {

        // If this is the first time that the TrackRevisions

        // propety is being disabled

        if (TrackChangesManager.trackRevisionsDisabledCounter == 0)

        {

            // Remember the value of the TrackRevisions property

            TrackChangesManager.trackRevisions =

                Globals.ThisDocument.TrackRevisions;

 

            // Set the value of TrackRevisions to false

            Globals.ThisDocument.TrackRevisions = false;

        }

 

        // Increment the counter of how many times the

        // TrackRevisions property has been disabled

        // without restoring its original value

        TrackChangesManager.trackRevisionsDisabledCounter++;

    }

 

    ///

    ///     Restores the original value of the document's

    ///     TrackRevisions property.

    ///

    public static void RestoreTrackRevisionsSetting()

    {

        // If the counter is already 0 it means that

        // RestoreTrackRevisionsSetting is being

        // called without having called

        // RememberAndDisableTrackRevisionsSetting before

        if (TrackChangesManager.trackRevisionsDisabledCounter == 0)

        {

            throw new InvalidOperationException(

                "RestoreTrackRevisionsSetting can only be " +

                "called the same number of times that " +

                "RememberAndDisableTrackRevisionsSetting " +

                "has been called before it.");

        }

 

        // Decrement the counter of how many times the

        // TrackRevisions property has been disabled

        // without restoring its original value

        TrackChangesManager.trackRevisionsDisabledCounter--;

 

        // If RestoreTrackRevisionsSetting has been called

        // as many times as RememberAndDisableTrackRevisionsSetting

        // has been called, restore the original value

        // of the TrackRevisions property.

        if (TrackChangesManager.trackRevisionsDisabledCounter == 0)

        {

            Globals.ThisDocument.TrackRevisions =

                TrackChangesManager.trackRevisions;

        }

    }

}

Its usage is pretty straightforward:

 

// Turn track changes off and remember its original setting

TrackChangesManager.RememberAndDisableTrackRevisionsSetting();

 

try

{

    // Insert complex custom logic here

}

finally

{

    // Restore the track changes setting

    TrackChangesManager.RestoreTrackRevisionsSetting();

}