none
Multiple ContentControls

    Question

  • I am building a Word document dynamically of RichTextContentControls but when I add a second control of the same name I get the following error - "The control cannot be added because a control with the name EM.Address1 already exists in the Controls collection."  I have tried setting the following fields to be unique - PlaceholderText, Text, Title, and Tag but does not seem to make a differnce.  Which property needs to be unique to allow for this?

    Thanks

    Scott

    Monday, April 20, 2009 7:59 PM

Answers

  • Hi Scott

    I'm not sure I understand why you're trying to do this, but I do understand why you cannot.

    You're dealing with two things when you create an object in an Office document that also belongs to the VSTO Controls collection: 1. the native Office object (a content control) and 2. A VSTO object that wraps the native object in order to extend its capabilities.

    Only the latter of these is added to the VSTO Controls collection, and only the VSTO control has a Name property. This property serves as a unique identifier (an index value on the collection), so you can't have two of them on the same document.

    The native Word object is designed differently: the only unique identifier/indexer it has is the GUID (the ID property). The Title and Tag can both be assigned values used by other content controls. Because this is the case, one needs to use the SelectContentControlsByTitle (or SelectContentControlsByTag), which returns an array, in order to access a content control by its Title or Tag. When working with the Controls collection, this is not necessary because you can assign a unique Name property.

    The reason the ContentControls collection was designed in this manner was to allow multiple Content Controls to display the same content (through their XMLMapping) and the same XML validation through an attached schema.
    Cindy Meister, VSTO/Word MVP
    Tuesday, April 21, 2009 7:43 AM

All replies

  • Hi Scott

    I'm not sure I understand why you're trying to do this, but I do understand why you cannot.

    You're dealing with two things when you create an object in an Office document that also belongs to the VSTO Controls collection: 1. the native Office object (a content control) and 2. A VSTO object that wraps the native object in order to extend its capabilities.

    Only the latter of these is added to the VSTO Controls collection, and only the VSTO control has a Name property. This property serves as a unique identifier (an index value on the collection), so you can't have two of them on the same document.

    The native Word object is designed differently: the only unique identifier/indexer it has is the GUID (the ID property). The Title and Tag can both be assigned values used by other content controls. Because this is the case, one needs to use the SelectContentControlsByTitle (or SelectContentControlsByTag), which returns an array, in order to access a content control by its Title or Tag. When working with the Controls collection, this is not necessary because you can assign a unique Name property.

    The reason the ContentControls collection was designed in this manner was to allow multiple Content Controls to display the same content (through their XMLMapping) and the same XML validation through an attached schema.
    Cindy Meister, VSTO/Word MVP
    Tuesday, April 21, 2009 7:43 AM
  • So how would/should I acommplish the following?  I have a listbox with a list of database fields such as EM.LastName, EM.FirstName, EM.Title that I am inserting into the Word document as ContentControls.  If you want to insert the EM.LastName content control into two or more places in the document, how can I accomplish that?  Here is the code I am using to insert the ContentControl.

    Public Sub DropContentControl(ByVal i As String)
            Dim richTextControl1 As Microsoft.Office.Tools.Word.RichTextContentControl
            Try
                richTextControl1 = Globals.ThisDocument.Controls.AddRichTextContentControl(i)
                Globals.ThisDocument.ToggleFormsDesign()
                richTextControl1.PlaceholderText = i
                richTextControl1.Title = i 
                richTextControl1.Tag = i 
                richTextControl1.Text = i 
                Globals.ThisDocument.ToggleFormsDesign()
            Catch ex As Exception
                MsgBox(ex.ToString)
            End Try
    End Sub


    Thanks

    Scott
    Tuesday, April 21, 2009 1:18 PM
  • So how would/should I acommplish the following?  I have a listbox with a list of database fields such as EM.LastName, EM.FirstName, EM.Title that I am inserting into the Word document as ContentControls.  If you want to insert the EM.LastName content control into two or more places in the document, how can I accomplish that?  Here is the code I am using to insert the ContentControl.
    Hi Scott

    I don't see where your code sample is setting the Name property of richtTextControl1? You could, for example, name the control for the field with an incrementing number (EmLastName1, EmLastName2, etc) Track the number at the class level, and assign the name with the incremented number.

    If you need to quickly access all controls for a single field, assign them to an array/list/collection.

    Note that you could also write the data for a database record to an XML file, insert that as a CustomXMLPart, and link the fields to that. This would save you needing to write data to the fields in your code. If the user types something different in a content control, it will be written to the XML part and also appear in the other controls mapped to the same field. If the user changes the database record, change the XML, using standard XML tools in the .NET framework.

    Cindy Meister, VSTO/Word MVP
    Wednesday, April 22, 2009 9:11 AM