Get a CheckBox in Word using OpenXML

荒凉一梦 提交于 2019-11-30 09:24:55

The code below shows how to enumerate all checkboxes in a word document by using the Decendants<CheckBox>() method on the docuement's body.

using (WordprocessingDocument doc = WordprocessingDocument.Open("c:\\temp\\checkbox.docx", true))
{
  foreach (CheckBox cb in doc.MainDocumentPart.Document.Body.Descendants<CheckBox>())
  {
    Console.Out.WriteLine(cb.LocalName);

    FormFieldName cbName = cb.Parent.ChildElements.First<FormFieldName>();
    Console.Out.WriteLine(cbName.Val);

    DefaultCheckBoxFormFieldState defaultState = cb.GetFirstChild<DefaultCheckBoxFormFieldState>();
    Checked state = cb.GetFirstChild<Checked>();

    Console.Out.WriteLine(defaultState.Val.ToString());

    if (state.Val == null) // In case checkbox is checked the val attribute is null
    {
      Console.Out.WriteLine("CHECKED");
    }
    else
    {
      Console.Out.WriteLine(state.Val.ToString());
    }
  }
}

To determine the name of a given checkbox input element you have to access the Parent property of the CheckBox instance and then search for the FormFieldName element (to assign a name to a checkbox use the Properties Dialog in Microsoft Word).

The DefaultCheckBoxFormFieldState Val property holds the default state for the checkbox. Furthermore the Val property of the Checked element holds the actual checked state of the CheckBox instance. Note, for Microsoft Word 2007 the Val property is null if the checkbox is checked.

BEGIN EDIT

I'd like to extend my answer. In fact, there are two kinds of checkbox controls on the MS Word developer tab - a legacy checkbox and an ActiveX control checkbox. The code shown above can be used to enumerte legacy checkboxes in a word document (see this article on how to create a legacy checkbox).

As far as I know, you can't use the OpenXML SDK to get/set values for an ActiveX checkbox. However you can enumerate ActiveX controls using the following code:

foreach (Control ctrl in doc.MainDocumentPart.Document.Body.Descendants<Control>())
{
   Console.Out.WriteLine(ctrl.Id);
   Console.Out.WriteLine(ctrl.Name);
   Console.Out.WriteLine(ctrl.ShapeId);
}

To determine whether or not a given Control is a checkbox you have to ckeck the class ID of the Control. The class ID of a checkbox is {8BD21D40-EC42-11CE-9E0D-00AA006002F3}. Here is a code sample to get the class ID (I don't know if there is an easier way...):

OpenXmlPart part = doc.MainDocumentPart.GetPartById(ctrl.Id);
OpenXmlReader re = OpenXmlReader.Create(part.GetStream());
re.Read();
OpenXmlElement el = re.LoadCurrentElement();          
if(el.GetAttribute("classid", el.NamespaceUri).Value == "{8BD21D40-EC42-11CE-9E0D-00AA006002F3}")
{
  Console.WriteLine("Checkbox found...");
}
re.Close();

END EDIT

EDIT 2

I didn't realize that there is a new checkbox control in Word 2010 (Thanks to Dennis Palmer).

To enumerate those new checkbox controls you can use the following code:

using (WordprocessingDocument doc = WordprocessingDocument.Open(filename, true))
{
   MainDocumentPart mp = doc.MainDocumentPart;

   foreach(SdtContentCheckBox cb in mp.Document.Body.Descendants<SdtContentCheckBox>())
   {         
     if(cb.Checked.Val == "1");
     {
       Console.Out.WriteLine("CHECKED");  
     }           
   }
}

END EDIT 2

Hope, this helps.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!