Search code examples
c#ms-wordopenxmlword-contentcontrol

How to block access to content controls - open xml


I'm reading content control from docx by its tag. And I want to block acces to it (user will not be able to edit content). How can I do that? Here is my code for getting control by its tag name from docx document:

using (WordprocessingDocument wordDocTarget = WordprocessingDocument.Open(targetFilePath, true))
{
      MainDocumentPart mainPartSource = wordDocSource.MainDocumentPart;
      SdtBlock sdtBlock = mainPartSource.Document.Body.Descendants<SdtBlock>().Where(r => r.SdtProperties.GetFirstChild<Tag>().Val == "myTagName").SingleOrDefault();

      // rest of my code (editing inner text) 
}

Solution

  • You can insert a Lock (<w:lock>) element in the SdtProperties-element - that will make the content read-only. For example this defines a plain text content control containing the text 'hello' which appears read-only when editing the document in Word:

    <w:document>
        <w:body>
            <w:sdt>
                <w:sdtPr>
                    <w:lock w:val="contentLocked" />
                    <w:text />
                </w:sdtPr>
                <w:sdtContent>
                    <w:p>
                        <w:r>
                            <w:t>hello</w:t>
                        </w:r>
                    </w:p>
                </w:sdtContent>
            </w:sdt>
      ...
      </w:body>
    </w:document>
    

    In code you can use something like this to add the lock:

    using (var document = WordprocessingDocument.Open(@"c:\temp\test.docx", true))
    {
        SdtBlock sdtBlock = 
            document
            .MainDocumentPart
            .Document
            .Body
            .Descendants<SdtBlock>()
            .Where(b => b.SdtProperties.GetFirstChild<Tag>().Val == "myTagName")
            .SingleOrDefault();
    
        var contentLock = new Lock { Val = LockingValues.SdtContentLocked };
        sdtBlock.SdtProperties.AppendChild(contentLock);
    }
    

    I find it usefull to start with a Word-document and then use OpenXML Productivity Tool to see the xml produced by Word.