Best practice for Serializing state data in a word doc Add in.
I have a Word 2007 Add-In implemented in .Net. I have implemented a variety of content controls which attach and display our data sources using the office tools library.
I have various programatic state data which is not visible to the user but is used by the content controls to connect and display the data. Where should I serialize the programatic state data?
Ideally it would be inside the document file and would just get read and written on doc startup and shutdown.
If that wont work I guess I can serialize to an external xml file. But that is clumsy. What if the user loses the extra file.
A solution that works in Word 2003 as well would be nifty.
thanks
Karl
Answers
Hi Karl
As long as what you want to serialize is "plain text" (which would be the case for XML), you can write it to the Word object VARIABLE, a property of the Document object.
Word's document variables offer storage capability within the document's structure. This information is (in contrast to a document property) not visible in the user interface.
Please note that a document Variable object may not contain a zero-length string. Word will delete the document variable object as soon as it contains "nothing" - it must always contain at least one character. Although the object model provides an ADD method, you don't need to use it. Simply assigning a string value to Document.Variables("TheName") will create and populate the object.
With Word 2007 I'd think you'd also have the option of creating a new CustomPart in the document and dumping your XML in that. Just don't link it to a content control...
All Replies
Hi Karl
As long as what you want to serialize is "plain text" (which would be the case for XML), you can write it to the Word object VARIABLE, a property of the Document object.
Word's document variables offer storage capability within the document's structure. This information is (in contrast to a document property) not visible in the user interface.
Please note that a document Variable object may not contain a zero-length string. Word will delete the document variable object as soon as it contains "nothing" - it must always contain at least one character. Although the object model provides an ADD method, you don't need to use it. Simply assigning a string value to Document.Variables("TheName") will create and populate the object.
With Word 2007 I'd think you'd also have the option of creating a new CustomPart in the document and dumping your XML in that. Just don't link it to a content control...
Storing xml text in Variables works great. Thanks Cindy.
But I am still having an issue with serializing the controls.
In the first session, on an empty document, I add a control with
_document.Controls.AddPlainTextContentControl( range, name );
and insert the control into the text of the document.
Then I save the document from the UI.
Then I open the document again for session 2.
The control is in the document but I can not seem to get to it programatically
When I look at
_document.Controls.Count == 0
and
_document.ContentControls.Count == 1
If I do
object index=1;
_document.ContentControls.get_Item( ref idx )
I get a COM object which will not let me cast it to a PlainTextContentControl
But I can see the control from the UI in session 2. So it is there in some form.
Did I need to do something special to make the content control save out?It looks like you're working with the new VSTO-specific content controls (that is, controls in the Microsoft.Office.Tools.Word namespace) in a Word Document or Word Template project. The problem you're running into is that when you programmatically add a VSTO-specific control to a document at run time by using one of the ThisDocument.Controls.Add<control name> methods, the VSTO control isn't persisted in the document - when the user closes the document, it is automatically removed from the document.
However, the underlying "native" content control (that is, the Microsoft.Office.Interop.Word.ContentControl) remains behind. This is why the _document.ContentControls.Count property in your project has a value of 1. The ContentControls property returns the collection of native content controls, whereas the Controls property returns the collection of VSTO-specific controls). For more reading about working with dynamically created controls in VSTO projects, see http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2656017&SiteID=1.
To simulate persistence of content controls that you add to the document at run time, you will need to recreate any VSTO content controls in the document when it is opened. One option is to loop through the document, and for each native Microsoft.Office.Interop.Word.ContentControl in the document, use the Add<control name> method overload that takes a native content control. For example, to recreate a dynamically created PlainTextContentControl, use the Microsoft.Office.Tools.Word.ControlCollection.AddPlainTextContentControl(ContentControl, String) method (see http://msdn2.microsoft.com/en-us/library/bb398662.aspx). You can then deserialize your custom state data and use it to configure each control as appropriate.
Also, since it appears that you're working with a document-level project (as opposed to an application-level add-in), an alternative way to save data in the document is to save it to the data cache in the document. To do this, simply apply the Microsoft.VisualStudio.Tools.Applications.Runtime.Cached attribute to any public and serializable field or property of the ThisDocument class in your solution. For more information, see http://msdn2.microsoft.com/en-us/library/ms178808.aspx and http://msdn2.microsoft.com/en-us/library/7230ebaf.aspx.
Finally, note that content controls are available only in Word 2003 (your first post mentioned a solution that could work in Word 2003 too).
I hope this helps,
McLean Schofield
Yep I just got that working.
At startup I manually repopulate _document.Controls from _document.ContentControls.
It is a kinda goofy gotcha. I was convinced it was a bug...
>Finally, note that content controls are available only in Word 2003 (your first post mentioned a solution that could work in Word 2003 too).
Did you mean content controls are only supported in 2007?
Yeah. But they are really handy. I was going to get things working with content controls in 2007 and then try to emuate them in 2003 with either Com components or Booksmarks or something.
I will have to check out the data cache too and see if it useful what what I am doing.
Storing things in text document.Variables as xml makes sense for my app because I need the xml for other things anyway.
Thanks for the help!
I am just getting used to VSTO.
Karl

