Ottieni un CheckBox in Word usando OpenXML

Come si ottiene un handle per un controllo CheckBox incorporato in un documento Word che utilizza OpenXML?

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

Posso attraversare la struttura del documento utilizzando la struttura XML effettiva, ma questo sembra complicato.

Suggerimenti benvenuto

    Il codice seguente mostra come enumerare tutte le checkbox in un documento word usando il Decendants() sul corpo del documento.

     using (WordprocessingDocument doc = WordprocessingDocument.Open("c:\\temp\\checkbox.docx", true)) { foreach (CheckBox cb in doc.MainDocumentPart.Document.Body.Descendants()) { Console.Out.WriteLine(cb.LocalName); FormFieldName cbName = cb.Parent.ChildElements.First(); Console.Out.WriteLine(cbName.Val); DefaultCheckBoxFormFieldState defaultState = cb.GetFirstChild(); Checked state = cb.GetFirstChild(); 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 checkbox è necessario accedere alla proprietà Parent dell’istanza CheckBox e quindi cercare l’elemento FormFieldName (per assegnare un nome a una casella di controllo, utilizzare la finestra di dialogo Proprietà in Microsoft Word).

    La proprietà DefaultCheckBoxFormFieldState contiene lo stato predefinito per la casella di controllo. Inoltre la proprietà Val dell’elemento Checked contiene lo stato verificato effettivo dell’istanza CheckBox . Nota, per Microsoft Word 2007 la proprietà Val è null se la casella è selezionata.

    INIZIA MODIFICA

    Mi piacerebbe estendere la mia risposta. In effetti, ci sono due tipi di controlli checkbox nella scheda dello sviluppatore di MS Word: una casella di controllo legacy e una casella di controllo controllo ActiveX. Il codice mostrato sopra può essere utilizzato per enumerare le caselle di controllo legacy in un documento word (vedere questo articolo su come creare una casella di controllo legacy).

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

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

    Per determinare se un determinato Control è una casella di controllo devi ckeck l’ID di class del Control . L’ID class di una casella di controllo è {8BD21D40-EC42-11CE-9E0D-00AA006002F3} . Ecco un esempio di codice per ottenere l’ID della class (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 MODIFICA

    MODIFICA 2

    Non mi sono reso conto che c’è un nuovo controllo in Word 2010 (grazie a Dennis Palmer).

    Per enumerare questi nuovi controlli puoi usare il seguente codice:

     using (WordprocessingDocument doc = WordprocessingDocument.Open(filename, true)) { MainDocumentPart mp = doc.MainDocumentPart; foreach(SdtContentCheckBox cb in mp.Document.Body.Descendants()) { if(cb.Checked.Val == "1"); { Console.Out.WriteLine("CHECKED"); } } } 

    END EDIT 2

    Spero che questo ti aiuti.