Associating Data with Content Controls
**
Background reading
What is Custom XML- ... and the impact of the i4i judgment on Word,
Regarding Custom XML Patch distribution and availability,
Using Content Controls vs. Custom XML Elements,
Scanning tool to detect documents with custom XML
By popular demand, Eric White has returned to provide more guidance regarding the use of Content Controls. Eric's guest post today outlines more of how you can use Content Controls in your environment.
......
In a previous post on Gray's blog, I discussed an approach for building a content publishing system using styles and content controls. This is only one of the scenarios where content controls are useful. Another scenario is where you have a sophisticated document generation system where content controls are replaced with automatically generated text. The replacement instructions could be fairly elaborate - perhaps including the database server name, table name, filter, and column name, for example. In a different scenario, you may have a system that automates testing of code listings that are contained in documents, and you may have build instructions for each snippet in the document. I blogged about this approach in OpenXmlCodeTester: Validating Code in Open XML Documents.
Note: I co-wrote this post with Anil Kumar. Many thanks to Anil for writing the managed add-in code.
In all of the above scenarios, you may have the need to associate arbitrary amounts of data with each content control. You may also have the requirement that the document author can create and edit this auxiliary information. Content controls don't directly have a facility for storing and maintaining such information, but there is a fairly easy approach to solving this problem.
Note: In this post, I refer to 'custom XML parts'. Open XML documents are stored using the Open Packaging Conventions. They are essentially zip files (packages) that contain multiple XML and other types of files (parts) within them. These parts are related to each other by a very specific mechanism called relationships. A custom XML part is a part (a file in XML format) of your own design stored in the package. You can design your own XML vocabulary for this part. I've written an MSDN article, The Essentials of Open Packaging Conventions, which explains what you need to know to work with packages and parts. 'Custom XML parts' in this sense are not affected by January 2010 update for Office Word that Gray has blogged about previously . Custom XML parts will continue to be supported in Word.
The gist of the technique for associating data with content controls is as follows:
You create a custom XML part that contains some XML that looks something like this:
If you need to maintain more than one value for each content control, you can have as many child elements of the Content element as necessary.
Each content control contains a unique ID that is assigned by Word upon creation of the content control. The data in the custom XML part is related to the content control using this ID. Following is the markup for one of the content controls that is related to the above XML:
You can make it easy for users to edit this auxiliary information in a custom task pane. To create this functionality, you create an Office managed add-in. When the focus is in a content control, the task pane is updated with information from the custom XML part, and when the user updates the data, the managed add-in updates the custom XML part. The following screen shot shows the task pane that is created by the example presented in this post:
As the user moves from content control to content control, the example updates the contents of the task pane. If the user moves to text in the document that is not in a content control, the example clears the text box in the task pane, and disables the "Update CustomXml Part" button. Another approach that you can take is to hide and show the task pane as the selection moves into and out of content controls. The example contains commented-out code that shows how to do this.
This example relies on the user pressing the "Update CustomXml Part" button. You may want to take another approach of updating the custom XML part data when the user changes any data in the task pane.
Custom Task Panes Overview provides a detailed explanation of custom task panes, and how to create them. Deploying a Visual Studio Tools for the Office System 3.0 Solution for the 2007 Microsoft Office System Using Windows Installer provides what you need to know to deploy an add-in.
There are three source files for this example:
ContentControlInfoAddIn.cs |
Implements the add-in, registers various event handlers, and creates and updates the custom XML part. |
ContentControlInfo.cs |
Contains the event handlers for the user control that is placed on the task pane. |
ContentControlInfo.Designer.cs |
Contains the designer generated code for the user control. |
You can download the code, along with a Visual Studio solution here.
Comments
Anonymous
January 01, 2003
You cannot use the Tag property if your fragment is over 64 characters. For some reason there is a 64 character limit on the Tag property.Anonymous
January 01, 2003
Interesting, Great to hear that you are finding success on the content control side. Regarding the nested controls, I am able to make this work without any trouble using two text controls or rich text controls. What control types are you adding? What Office product & version are you using?Anonymous
January 01, 2003
Excellent! This is exactly the guidance I was looking for! I had two problems with content controls, one being not able to specifying multiple properties/attributes for them. This post describes in detail that is IS possible and how to do it. My other problem with content controls is the way they are presented by Word (frame with a 'handle'): when I add a content control around a tablerow AND also add a content control around the first tablecell, I am no longer able to select the one around the table cell, because Word only lets me select the one around the table. Maybe you can give me a tip on how to work around this?Anonymous
January 25, 2010
We have been talking to Peter Amstein about this. We independently figured this method out and implemented it, but it's good to have the approach confirmed. Where it goes wrong is copy & paste. The user can copy & paste a (run containing a) content control. Unfortunately, we can't find any way to "hook" the paste event. The pasted content control gets a new ID which doesn't reference any node in our custom XML part, so when we later find one disconnected like this we can clearly identify what's happened to it, but equally we can't identify which was the source "copied" content control. As in our application those extra attributes were really important, this breaks the copy & paste semantics and therefore the user experience. Any suggestions would be most welcome.Anonymous
January 26, 2010
Can't you put all your custom attributes in an XML-fragment which you serialize in the Tag-property? I assume the standard tag-value DOES get copied?