0
votes

Is there an easy/straightforward way to dynamically add (not edit the value of) multiple checkbox controls in a .docx document body?

I tried appending a single SdtContentCheckBox after a new paragraph like this but with no luck:

newParagraph.Append(new SdtContentCheckBox());

and also followed the instructions here: https://www.codeproject.com/Tips/370758/Add-dynamic-content-controls-to-a-word-document and here: How do I create a check box in C# using Open XML SDK

The first one showed only how to add a text content control and the second one straight up resulted in a corrupted .docx file.

Any help would be appreciated!

2
Come on guys, I can't believe nobody has ever wanted to add clickable checkboxes programmatically!Themos

2 Answers

0
votes

Closest working code I could find was this:

https://social.msdn.microsoft.com/Forums/office/en-US/f6ce8ecf-0ed8-4f18-958a-a086f212d1e2/how-to-create-a-checked-checkbox-form-field-using-the-sdk?forum=oxmlsdk

public static Paragraph GenerateParagraph()  
    {  
        var element =   
            new Paragraph(  
                new Run(  
                    new FieldChar(  
                        new FormFieldData(  
                            new FormFieldName(){ Val = "Check1" },  
                            new Enabled(),  
                            new CalculateOnExit(){ Val = BooleanValues.Zero },  
                            new CheckBox(  
                                new AutomaticallySizeFormField(),  
                                new DefaultCheckboxFormFieldState(){ Val = BooleanValues.Zero }))  
                    ){ FieldCharType = FieldCharValues.Begin }),  
                new BookmarkStart(){ Name = "Check1", Id = 0 },  
                new Run(  
                    new FieldCode(" FORMCHECKBOX "){ Space = "preserve" }),  
                new Run(  
                    new FieldChar(){ FieldCharType = FieldCharValues.End }),  
                new BookmarkEnd(){ Id = 0 },  
                new Run(  
                    new Text("My check box"))  
            ){ RsidParagraphAddition = "00784880", RsidRunAdditionDefault = "00B77989" };  
        return element;  
    } 

Using this I was able to dynamically add Legacy Checkboxes (i.e. neither Content control nor ActiveX control), but at least it is a start!

If someone knows how to add Checkbox Content controls, feel free to post a reply below and I'll mark it as Correct.

-1
votes

Even though you found yourself the answer, I'll leave this here in case anyone stumbles upon this looking for something related.

There's a tool called Open XML SDK 2.5 Productivity Tool, which you can download from here that allows you to reverse-engineer a word .docx document to obtain the C# code to generate it from scratch.

In order to get the code that you are looking for to generate any kind of word element (a checkbox, a table, a bulleted list...), you need to create a word document with said element and save it.

Then, open it using the Open XML SDK 2.5 Productivity Tool and click on the "Reflect Code" button. The generated code will show you how to create those elements, styles and other formatting included.

With that, I got the code necessary to get a paragraph with a checkbox

using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using A = DocumentFormat.OpenXml.Drawing;
using DW = DocumentFormat.OpenXml.Drawing.Wordprocessing;
using PIC = DocumentFormat.OpenXml.Drawing.Pictures;

public static Paragraph GenerateCheckboxParagraph(string internalName, int internalId, string textAfterTextbox)
{
    var run1 = new Run(
            new FieldChar(
                new FormFieldData(
                    new FormFieldName() { Val = internalName },
                    new Enabled(),
                    new CalculateOnExit() { Val = OnOffValue.FromBoolean(false) },
                    new CheckBox(
                        new AutomaticallySizeFormField(),
                        new DefaultCheckBoxFormFieldState() { Val = OnOffValue.FromBoolean(false) }))
            )
            {
                FieldCharType = FieldCharValues.Begin
            }
        );
    var run2 = new Run(new FieldCode(" FORMCHECKBOX ") { Space = SpaceProcessingModeValues.Preserve });
    var run3 = new Run(new FieldChar() { FieldCharType = FieldCharValues.End });
    var run4 = new Run(new Text(textAfterTextbox));

    var element =
        new Paragraph(
            run1,
            new BookmarkStart() { Name = internalName, Id = new StringValue(internalId.ToString()) },
            run2,
            run3,
            new BookmarkEnd() { Id = new StringValue(internalId.ToString()) },
            run4
        );
    return element;
}