none
Can't change content control text after document generation

    Question

  • Hello,

    I'm facing a problem with my document generation system.

    I'm working with document templates. These templates have some content controls in them.

    When a document is generated, the text of some rich text content control cannot be modified anymore manually!

    Does someone already met this behaviour and found the cause?

    Thanks

    Monday, February 11, 2013 1:19 PM

Answers

  • Thank you for the additional information

    I'd say, take a careful look at what the code you're NOT showing us generates for InnerXML for the rich text content controls. It might help if you type the equivalent into a rich content control and compare the XML result your code generates with what Word does when you type the text.

    Since we don't see the XML around the content control this is only a guess. But I suspect that the problem may have to do with the <w:p> tags.

    If you have your content control inside a paragraph:
       <w:p><w:std> more stuff here </w:std></w:p>
    Then you may NOT put any <w:p> tags inside the content control, only <br/>

    If you must embed <w:p> tags inside the content control, then the content control itself cannot be within <w:p>...</w:p> So in order to hold <w:p> the pattern must be:
      <w:p>A preceding paragraph</w:p><w:sdt><w:p> Stuff</w:p><w:p> here </w:p></w:std><w:p>start of a new paragraph

    You can test this easily enough in the Word UI: Word won't let you type ENTER in a content control that's inside a paragraph. If the content control stands alone in a paragraph, the Word UI will incorporate the paragraph mark into the content control as soon as you press ENTER. Open XML doesn't take care of this for you - you have to watch out for it.


    Cindy Meister, VSTO/Word MVP, my blog

    • Marked as answer by Yvkevitch Wednesday, February 13, 2013 8:31 AM
    Wednesday, February 13, 2013 8:24 AM

All replies

  • Hi Yvkevitch,

    Thanks for posting in the MSDN Forum.

    Would you please share your code for further trouble shooting?

    Let's see whether you forgot save the change for the document.

    Have a good day,

    Tom


    Tom Xu [MSFT]
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, February 12, 2013 8:36 AM
  • It would be helpful if you could show us the end-result (XML mark-up in document.xml) of such a content control. And the code that generates it.

    Cindy Meister, VSTO/Word MVP, my blog

    Tuesday, February 12, 2013 8:41 AM
  • Here is the resulting XML of one of the content control

    <w:sdt>
          <w:sdtPr>
            <w:alias w:val="#DDT#RensCompContacts" />
            <w:tag w:val="#DDT#RensCompContacts:Rich" />
            <w:id w:val="1826631538" />
            <w:placeholder>
              <w:docPart w:val="410CDCF4C2C6401E92D01D475946A1FF" />
            </w:placeholder>
            <w:showingPlcHdr />
          </w:sdtPr>
          <w:sdtEndPr />
          <w:sdtContent>
            <w:p>
              <w:r>
                <w:t>Madame John Doe, Responsable des achats</w:t>
              </w:r>
              <w:r>
                <w:br />
                <w:t>(Tél : 04/2540000, e-mail : j.doe@contoso.com)</w:t>
              </w:r>
            </w:p>
            <w:p>
              <w:r>
                <w:t>Monsieur John Doe, Directeur du département informatique</w:t>
              </w:r>
              <w:r>
                <w:br />
                <w:t>(Tél : 04/2540000, e-mail : j.doe@contoso.com)</w:t>
              </w:r>
            </w:p>
          </w:sdtContent>
        </w:sdt>

    Tuesday, February 12, 2013 9:39 PM
  • And here is the code of the function that fill the document:

    For each content control, it take a name and a type (Plain text or Rich text) from the tag of the content control.
    According to the type and name, it fill the content control with text if it is a plain text content control or with xml if it is a rich text content control
    The problem is only with rich text content control.

            static private bool FillDocument(String p_Filename,ref MarchePublic p_MP, ref ModeleDocumentChoix p_MDC)
            {
                String strFileName = p_Filename;
                try
                {
                    using (WordprocessingDocument package = WordprocessingDocument.Open(strFileName, true))
                    {
                        MainDocumentPart mainPart = package.MainDocumentPart;
                        //Enregister les types de bloc pouvant accueillir des content controls
                        String sdtBlockType = new SdtBlock().GetType().ToString();
                        String sdtRunType = new SdtRun().GetType().ToString();
                        //Obtenir tout les content controls du document
                        IEnumerable<OpenXmlElement> ccBlocks = ContentControlExtensions.ContentControls(package);///mainPart.Document.Body.Descendants().Where(el => el is SdtBlock || el is SdtRun);
                        foreach (SdtElement ccBlock in ccBlocks)
                        {
                            SdtProperties ccBlockProperties = ccBlock.Elements<SdtProperties>().FirstOrDefault();
                            Tag ccTag = ccBlockProperties.Elements<Tag>().FirstOrDefault();
                            String CCName;
                            String CCType;
                            ContentControlExtensions.GetContentControlNameAndType(ccTag.Val,out CCName,out CCType);
                            if ((!String.IsNullOrEmpty(CCType) && CCType == "Plain") || String.IsNullOrEmpty(CCType))
                            {   
                                #region Plain text content controls
    		                    //Plain text content control
                                
                                IEnumerable<Text> texts = ccBlock.Descendants<Text>();
                                Text text = texts.ElementAt(0);
                                //objet dont on peut avoir besoin
                                Lieu lieu = null;
                                Site site = null;
                                switch (CCName)
                                { 
                                    case "Intitule":
                                        text.Text = p_MP.Intitule;
                                        break;
                                    case "DepotOffreDate":
                                        text.Text = p_MP.GetCaracteristique(MarchePublicData.DepotOffreDate);
                                        break;
                                    case "DepotOffreSite":
                                        lieu = LieuManager.Instance.GetLieu(p_MP.GetCaracteristiqueAsInt(MarchePublicData.DepotOffreLieu));
                                        site = SiteManager.Instance.GetSiteById(lieu.refSite);
                                        text.Text = "Site " + site.Nom;
                                        break;
                                    case "DepotOffreLieu":
                                        lieu = LieuManager.Instance.GetLieu(p_MP.GetCaracteristiqueAsInt(MarchePublicData.DepotOffreLieu));
                                        text.Text = lieu.Nom;
                                        break;
                                    default:
                                        text.Text = String.Format("###Champ [{0}] non reconnu lors de la génération du document###", CCName);
                                        break;
                                } 
    	                        #endregion
                            }
                            else 
                            {
                                #region Rich text content controls
                                //Rich text content control
     
                                //Get the XML
                                String InnerXML = String.Empty;
                                SdtContentBlock sdtContentBlock = null;
                                switch (CCName)
                                { 
                                    case "SitesConcernes":
                                        //sdtContentBlock = DocGenXML.Content_SitesConcernes(ref p_MP);
                                        InnerXML = DocGenXML.XML_SitesConcernes(ref p_MP);
                                        break;
                                    case "#DDT#DocsAFournir":
                                        InnerXML = DocGenXML.XML_DocsAFourir(CCName, ref p_MDC);
                                        break;
                                    case "#DDT#DepotOffreContact":
                                        InnerXML = DocGenXML.XML_DepotOffreContact(CCName,ref p_MDC);
                                        break;
                                    case "#DDT#RensCompContacts":
                                        InnerXML = DocGenXML.XML_RensComplContacts(CCName,ref p_MDC);
                                        break;
                                    case "#DDT#SurvExeContacts":
                                        InnerXML = DocGenXML.XML_SurvExeContacts(CCName, ref p_MDC);
                                        break;
                                    default:
                                        
                                        break;
                                } 
                                if (ccBlock.GetType().ToString() == sdtBlockType)
                                {
                                    SdtContentBlock ccBlockContent = ((SdtBlock)ccBlock).SdtContentBlock;
                                    ccBlockContent.InnerXml = InnerXML;
                                }
                                else if (ccBlock.GetType().ToString() == sdtRunType)
                                {
                                    SdtContentRun ccBlockContent = ((SdtRun)ccBlock).SdtContentRun;
                                    ccBlockContent.InnerXml = InnerXML;
                                }
                                else
                                {
                                }
                                #endregion
                            }
                        }
                    }
                }
                catch(Exception exc)
                {
                    LogEntry(LogType.Error, "FillDocument()", exc);
                }
                
                return true;
            }


    • Edited by Yvkevitch Tuesday, February 12, 2013 9:44 PM
    Tuesday, February 12, 2013 9:43 PM
  • Thank you for the additional information

    I'd say, take a careful look at what the code you're NOT showing us generates for InnerXML for the rich text content controls. It might help if you type the equivalent into a rich content control and compare the XML result your code generates with what Word does when you type the text.

    Since we don't see the XML around the content control this is only a guess. But I suspect that the problem may have to do with the <w:p> tags.

    If you have your content control inside a paragraph:
       <w:p><w:std> more stuff here </w:std></w:p>
    Then you may NOT put any <w:p> tags inside the content control, only <br/>

    If you must embed <w:p> tags inside the content control, then the content control itself cannot be within <w:p>...</w:p> So in order to hold <w:p> the pattern must be:
      <w:p>A preceding paragraph</w:p><w:sdt><w:p> Stuff</w:p><w:p> here </w:p></w:std><w:p>start of a new paragraph

    You can test this easily enough in the Word UI: Word won't let you type ENTER in a content control that's inside a paragraph. If the content control stands alone in a paragraph, the Word UI will incorporate the paragraph mark into the content control as soon as you press ENTER. Open XML doesn't take care of this for you - you have to watch out for it.


    Cindy Meister, VSTO/Word MVP, my blog

    • Marked as answer by Yvkevitch Wednesday, February 13, 2013 8:31 AM
    Wednesday, February 13, 2013 8:24 AM
  • Since we don't see the XML around the content control this is only a guess. But I suspect that the problem may have to do with the <w:p> tags.

    If you have your content control inside a paragraph:
       <w:p><w:std> more stuff here </w:std></w:p>
    Then you may NOT put any <w:p> tags inside the content control, only <br/>

    If you must embed <w:p> tags inside the content control, then the content control itself cannot be within <w:p>...</w:p> So in order to hold <w:p> the pattern must be:
      <w:p>A preceding paragraph</w:p><w:sdt><w:p> Stuff</w:p><w:p> here </w:p></w:std><w:p>start of a new paragraph

    You can test this easily enough in the Word UI: Word won't let you type ENTER in a content control that's inside a paragraph. If the content control stands alone in a paragraph, the Word UI will incorporate the paragraph mark into the content control as soon as you press ENTER. Open XML doesn't take care of this for you - you have to watch out for it.


    Cindy Meister, VSTO/Word MVP, my blog

    Many thanks Cindy...
    Wednesday, February 13, 2013 8:37 AM