Domanda

Come si fa a ottenere un handle a un controllo CheckBox che è incorporato in un documento di Word utilizzando OpenXML?

Si potrebbe pensare che sia Paragraph.ControlPropertiesPart o Paragraph.Descendents () sarebbe ottenere qualcosa, ma in ogni singolo caso ottengo un tipo nullo restituito.

posso attraversare l'albero documento utilizzando la struttura XML vero e proprio, ma questo sembra ingombrante.

I suggerimenti sono benvenuti.

È stato utile?

Soluzione

Il codice seguente mostra come enumerare tutte le caselle di controllo in un documento di Word utilizzando il metodo Decendants<CheckBox>() sul corpo del docuement.

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

Per determinare il nome di un dato elemento di input casella di controllo è necessario accedere al Proprietà Parent dell'istanza CheckBox e quindi cercare l'elemento FormFieldName (per assegnare un nome ad un uso casella finestra di dialogo Proprietà in Microsoft Word).

La proprietà DefaultCheckBoxFormFieldState Val mantiene lo stato di default per la casella di controllo. Inoltre, la struttura Val dell'elemento Checked mantiene lo stato attuale controllato dell'istanza CheckBox. Nota, per Microsoft Word 2007 la proprietà Val è null se la casella è selezionata.

BEGIN EDIT

Mi piacerebbe estendere la mia risposta. In realtà, ci sono due tipi di controlli casella di controllo nella scheda Sviluppo MS Word - una casella di controllo legacy e una casella di controllo ActiveX. Il codice mostrato sopra può essere utilizzato per le caselle di controllo legacy enumerte in un documento word (vedi questo articolo su come creare una casella di controllo legacy).

Per quanto ne so, non è possibile utilizzare l'OpenXML SDK per ottenere / valori impostati per una casella di controllo ActiveX. Tuttavia è possibile enumerare i controlli ActiveX utilizzando il seguente codice:

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

Per determinare se una data Control è una casella di controllo è necessario ckeck l'ID di classe del Control. L'ID di classe di una casella di controllo è {8BD21D40-EC42-11CE-9E0D-00AA006002F3}. Ecco un esempio di codice per ottenere l'ID di classe (non so se c'è un modo più semplice ...):

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

FINE EDIT

Modifica 2

Non si rendeva conto che c'è un nuovo controllo casella di controllo in Word 2010 (grazie a Dennis Palmer).

Per enumerare questi nuovi controlli casella di controllo è possibile utilizzare il seguente codice:

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

FINE EDIT 2

La speranza, questo aiuta.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top