I'm trying to inject some paragraphs in a Word content control using Open Xml SDK.
My code seems to work (paragraphs are visible in the word file). However, control controls cannot be edited. I can only erase the whole content before inserting new content.
How to mimic a manual copy/paste into a content control ?
FYI, here's my code:
var mainPart = package.MainDocumentPart;
var sdtRuns = mainPart.Document.Descendants<SdtElement>().Where(run => run.SdtProperties.GetFirstChild<Tag>().Val.Value == "TagOfMyContentControl");
foreach (var sdtBlock in sdtRuns)
{
List<Paragraphs> paragraphs = GetParapraphsFromSomewhere();
var contentControlParagraph = sdtBlock.Descendants<SdtContentBlock>().First();
contentControlParagraph.RemoveAllChildren();
contentControlParagraph.Append(paragraphs);
}
mainPart.Document.Save();
PS: I a more general way, is there any resource that explains purpose and hierarchy of Word ML elements?
Your code is close to mimic copy paste into a content control. The following two lines are the lines that are removing all of the paragraphs in your content control:
var contentControlParagraph = sdtBlock.Descendants<SdtContentBlock>().First();
contentControlParagraph.RemoveAllChildren();
Instead, you need to determine where you want to place your paragraph and Append
it there.
For example, I have a docx with the rich text content control named CopyPasteCC. This image shows the doc in developer mode. The content control has 3 existing paragraphs.
Then, I replace your code with the following:
var mainPart = document.MainDocumentPart;
var sdtRuns = mainPart.Document.Descendants<SdtElement>().Where(run => run.SdtProperties.GetFirstChild<Tag>().Val.Value == "CopyPasteCC");
sdtRuns.ElementAt(0).Descendants<Paragraph>().ElementAt(1).InsertAfterSelf(
new Paragraph(new Run(new Text("Hello - this is new Copy Paste paragraph")))
);
mainPart.Document.Save();
The third line selects all of the paragraphs inside the content control found on the second line. Then it inserts a new paragraph after the second existing paragraph. The following image is the above file after this code has ran:
To answer your PS question - there is the formal OpenXML Specification you can try to read. This is not easy reading, but it is the authoritative specification. There is a more general (but dated) free e-book titled OpenXml Explained.
I reference each of these once a month for information. The first chapter of OpenXml Explained covers WordprocessingML
, and on page 39 there is a section on Structured Document Tags which has an overview of content controls.