In previous posts I talked about adding a toolbar
to Word as part of your VSTO project. What I am about to describe here is
particularly vital for this functionality, but it is related to most
customizations that you make to Word through your VSTO project.
Although you might not realize it, and it is certainly not what I expected
to happen by default, when you have a VSTO project regardless of whether you
choose to create a "document" or "template" project, any
changes that you make to Word through code eventually become part of the
global template Normal.dot (for more information about Normal.dot have a look here
and here).
You might be thinking, well is that such a bad thing? Consider the following
scenario. You have a VSTO Office Word Template project and part of
its functionality is to add a toolbar. As explained in my previous
related post, your code has to first check if the toolbar already exists
and only then, if it does not exist, should it attempt to add it. With the
toolbar being saved in the global template Normal.dot by default, after the
first time your project is executed on a machine the toolbar will always exist.
Also get this, your toolbar will continue to exist even after you have
uninstalled your project from the machine (unless of course you take steps to
either delete the global template Normal.dot or you write custom code that will
open the template and delete the toolbar). Now imagine you install a new
version of your project to this same machine, and your new version adds a few
more buttons to the toolbar. When your new code executes for the
first time it will check if the toolbar already exists and the answer will be
yes, because the older version of the toolbar was saved in the global template
Normal.dot. Your code will then skip the part of adding the toolbar and the new
buttons will never be added. Even worse, your code might try to reference those
new buttons that are supposed to be there and fail.
The solution is simple, you need to save the customizations that you make to
Word in your own template and not the global template Normal.dot. I would have
expected this to be the default behavior when you have a VSTO Word Template
project, but there you have it. So how do you instruct Word to do the
"right" thing? The title of the post gives it away, the following is
the code you would use to do it
// Go through each template available in the current application
foreach (Word.Template template in Globals.ThisDocument.Application.Templates)
{
// If the template is this project's template
if (String.Compare(template.Name, Constants.TEMPLATE_NAME) == 0)
{
// Set this template to be the one changes are made to
Globals.ThisDocument.Application.CustomizationContext = template;
break;
}
}
Some of you might be thinking, why go through
each template loaded in the currently application and not just use the
Document.AttachedTemplate property? The reason is that typically you would
change the customization context during the Document.StartUp event and at that
stage the template might not be attached to the document yet (well I don't know
if that is 100% true, but what I do know is that the property
Document.AttachedTemplate might return null).