Replacing Content Controls in OpenXML

Ingó Vals picture Ingó Vals · Aug 10, 2010 · Viewed 12.7k times · Source

I need something as a placeholder. I at first looked to Content Control as a solution but I'm having some problems with it.

I then looked into adding CustomXML to the .docx but turned away from that because of the i4i lawsuit.

Then I decided I would just plain change the text of the Content Control through OpenXML SDK 2.0 but even if it's so marked the Content Control doesn't go away. I guess that it doesn't know that the text changed unless it happens inside word.

I could perhaps just remove the CC and place text instead but I'm afraid of problems with format and styles it could bring and also it would kind of defy the purpose of the Content Control.

Then I started wondering if I could define my own placeholders that Word could recognize. Through Building blocks perhaps. It doesn't have to do anything except be easy to find using OpenXML and somehow taggable so I know what to replace it with. I'm not really sure what can be done with Building Blocks but I'm hoping it's do-able.

Not sure what solution would be best for me but what I need is:

a)Something that's easy to place in the template, perhaps predefined Content Control placeholders that you can place where you wan't and style as you like.

b)When the data has been added it removes all placeholders, it won't be modified again. It keeps the style/format defined in the placeholder.

TO RECAP, I need answer to either

How can I edit Content Controls in OpenXML SDK so they will be removed after text is added.

-OR-

Can I define my own custom OpenXML tag for a Word Document that I could then replace?

Answer

DevTun picture DevTun · Aug 19, 2010

Perhaps this can help you,

private void DeleteSdtBlockAndKeepContent(MainDocumentPart mainDocumentPart, string sdtBlockTag)
    {
        List<SdtBlock> sdtList = mainDocumentPart.Document.Descendants<SdtBlock>().ToList();
        SdtBlock sdtA = null;

        foreach (SdtBlock sdt in sdtList)
        {
            if (sdt.SdtProperties.GetFirstChild<Tag>().Val.Value == sdtBlockTag)
            {
                sdtA = sdt;
                break;
            }
        }


        OpenXmlElement sdtc = sdtA.GetFirstChild<SdtContentBlock>();
        OpenXmlElement parent = sdtA.Parent;

        OpenXmlElementList elements = sdtc.ChildElements;

        var mySdtc = new SdtContentBlock(sdtc.OuterXml);

        foreach (OpenXmlElement elem in elements)
        {

            string text = parent.FirstChild.InnerText;
            parent.Append((OpenXmlElement)elem.Clone());
        }

        sdtA.Remove();
    }