Setting Tags for Content Controls in a Word Document for Programmatically Updating Values

138 views Asked by At

I'm working on a project where I need to programmatically update the values of Content Controls in a Word document. I've successfully inserted Content Controls and tried to set tags for them but encountered some issues.

Here's the code

private void btnSubmit_Click(object sender, EventArgs e)
{
    GatherData();
    string docxFilePath = Path.Combine(executablePath, "CAR_Form.docx");
    string pdfFilePath = Path.Combine(executablePath, "CAR_Form.pdf");

    // Load the DOCX template
    using (WordprocessingDocument doc = WordprocessingDocument.Open(docxFilePath, true))
    {
        MainDocumentPart mainPart = doc.MainDocumentPart;

        // Define a list of tag-value pairs
        List<(string tag, string value)> tagValuePairs = new List<(string tag, string value)>
        {
            ("Respondent", respondent),
            ("GroupSec", group),
            ("IssueDate", issueDate),
            ("ResponseDate", responseDate),
            ("Requestor", requestor),
            ("CompanyDept", companyDept),
            ("ApprovedBy", approvedBy),
            ("CARNo", carNumber),
            ("ProblemDesc", problemDesc)
        };

        int emptyFieldCount = tagValuePairs.Count(pair => string.IsNullOrEmpty(pair.value));
        if (emptyFieldCount > 0)
        {
            MessageBox.Show(this, $"{emptyFieldCount} empty field(s) detected. Please provide a value for all placeholders.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        // Iterate through content controls and update them based on the tag-value pairs
        foreach (SdtElement contentControl in mainPart.Document.Descendants<SdtElement>())
        {
            var tag = contentControl.SdtProperties.Elements<Tag>().FirstOrDefault();
            if (tag != null)
            {
                string tagValue = tag.Val;
                var matchingPair = tagValuePairs.FirstOrDefault(pair => pair.tag == tagValue);
                Console.WriteLine($"Tag in Word: {tagValue}");
                Console.WriteLine($"Matching Pair: {matchingPair.tag} - {matchingPair.value}");
                if (matchingPair != default((string, string)))
                {
                    // Traverse nested content controls to find the SdtContentRun
                    SdtContentRun contentRun = contentControl.Descendants<SdtContentRun>().FirstOrDefault();
                    if (contentRun == null)
                    {
                        Console.WriteLine("ContentRun is null, checking nested controls...");
                        foreach (var innerControl in contentControl.Descendants<SdtElement>())
                        {
                            contentRun = innerControl.Descendants<SdtContentRun>().FirstOrDefault();
                            if (contentRun != null)
                            {
                                Console.WriteLine("ContentRun found in nested control.");
                                break; // Exit the loop once contentRun is found
                            }
                        }
                    }

                    if (contentRun != null)
                    {
                        Text text = contentRun.Descendants<Text>().FirstOrDefault();
                        if (text != null)
                        {
                            text.Text = matchingPair.value;
                            Console.WriteLine($"Updated text to: {matchingPair.value}");
                        }
                    }
                    else
                    {
                        Console.WriteLine("ContentRun is still null, check your document structure.");
                    }
                }
            }
        }

        // Save and close the modified document
        doc.Save();
        doc.Dispose();

        SaveAsPDF(docxFilePath, pdfFilePath);
    }

}

Problems

  1. Inserting Content Controls:
  • I've opened my Word document and inserted Content Controls via the "Developer" tab.
  • I've chosen Content Controls (Plain Text) on the data I need to capture.
  1. Setting Tags:
  • To identify and manipulate these Content Controls programmatically, I've tried to set tags for them.
  • In the "Developer" tab, I accessed the "Properties" dialog and entered unique tag names for each Content Control in the "Tag" field.
  1. Code for Updating Content:
  • I've written code in C# to open the Word document, access the Content Controls, and update their values based on the tags I've set.
  • My code iterates through the Content Controls and attempts to locate them by their tags.

The problem is that when I run my code, it doesn't seem to find the Content Controls based on the tags I've set. Specifically, the SdtContentRun elements within the Content Controls are null, and my code doesn't update the values.

Troubleshooting:

  • I've double-checked the tags in my Word document and the tags in my code, and they match.
  • I've ensured that my Content Controls are not deeply nested and are at the expected level within the document structure.

What could be causing my code to not find and update the Content Controls as expected? Are there any additional considerations or common pitfalls when working with Content Controls and tags in Word documents?

0

There are 0 answers