Получить CheckBox в Word, используя OpenXML - PullRequest
8 голосов
/ 01 декабря 2011

Как получить дескриптор элемента управления CheckBox, встроенного в документ Word с использованием OpenXML?

Можно подумать, что Paragraph.ControlPropertiesPart или Paragraph.Descendents () чего-то добьются, но в каждом отдельном случае я получаю возвращаемый нулевой тип.

Я могу пройти по дереву документа, используя фактическую структуру XML, но это кажется громоздким.

Предложения приветствуются.

1 Ответ

10 голосов
/ 04 декабря 2011

В приведенном ниже коде показано, как перечислить все флажки в текстовом документе, используя метод Decendants<CheckBox>() в теле документа.

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());
    }
  }
}

Чтобы определить имя данного элемента ввода флажка, необходимополучить доступ к свойству Parent экземпляра CheckBox, а затем выполнить поиск элемента FormFieldName (для присвоения имени флажку используйте диалоговое окно «Свойства» в Microsoft Word).

DefaultCheckBoxFormFieldState Val свойство содержит состояние по умолчанию для флажка.Кроме того, свойство Val элемента Checked содержит фактическое проверенное состояние экземпляра CheckBox.Обратите внимание, что для Microsoft Word 2007 свойство Val имеет значение null, если флажок установлен.

НАЧАТЬ РЕДАКТИРОВАТЬ

Я хотел бы расширить свой ответ.Фактически, на вкладке разработчика MS Word есть два вида элементов управления флажками - устаревшие и элементы управления ActiveX.Приведенный выше код можно использовать для перечисления устаревших флажков в текстовом документе (см. Эту статью о том, как создать устаревший флажок).

Насколько я знаю, вы не можетеиспользуйте OpenXML SDK, чтобы получить / установить значения для флажка ActiveX.Однако вы можете перечислить элементы управления ActiveX, используя следующий код:

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);
}

Чтобы определить, является ли данный Control флажком, необходимо щелкнуть идентификатор класса Control.Идентификатор класса флажка {8BD21D40-EC42-11CE-9E0D-00AA006002F3}.Вот пример кода для получения идентификатора класса (я не знаю, есть ли более простой способ ...):

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

РЕДАКТИРОВАТЬ 2

Я не осознавал, что в Word 2010 появился новый элемент управления флажками (спасибо Деннису Палмеру).

Чтобы перечислить эти новые элементы управления флажками, вы можете использовать следующий код:

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

Надеюсь, это поможет.

...