2011-12-01 24 views
8

Come si ottiene un handle per un controllo CheckBox incorporato in un documento di Word che utilizza OpenXML?Ottieni un CheckBox in Word utilizzando 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 ciò sembra complicato.

suggerimenti benvenuto.

+0

Si sta utilizzando un Controllo contenuto casella di controllo? – CoderDennis

risposta

10

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

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 alla proprietà Parent dell'istanza CheckBox e quindi cercare l'elemento FormFieldName (per assegnare un nome ad una casella di controllo utilizzare la finestra di dialogo Proprietà di Microsoft Parola).

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

BEGIN EDIT

vorrei 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 usato per enumicare le caselle di controllo legacy in un documento word (vedere questo article su come creare una casella di controllo legacy).

Per quanto ne so, non è possibile utilizzare l'SDK di OpenXML per ottenere/impostare valori 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 un dato Control è una casella di controllo è necessario ckeck l'ID di classe del Control. L'ID 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

EDIT 2

Non mi sono reso conto che esiste un nuovo controllo casella di controllo in Word 2010 (grazie a Dennis Palmer).

enumerare quelli nuova casella di controlli che è 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

Speranza, questo aiuta.

+0

Questo è quello che mi sarei aspettato che funzionasse, tranne che le tre caselle di controllo che ho inserito nel mio codice non vengono ancora prelevate. Non posso per la vita di me capire cosa ho fatto. A meno che non ci siano diversi tipi di checkbox. Ho creato un documento di esempio e ho inserito le caselle di controllo dal gruppo Controlli nella scheda Sviluppatore. –

+0

@ Phil.Wheeler: usi la casella di controllo ActiveX o il controllo della casella di controllo legacy? Nota, il codice sopra funziona solo con la casella di controllo legacy. – Hans

+0

Direi che era il controllo ActiveX. Si tratta di un documento nuovo di zecca creato appositamente e la casella di controllo è stata aggiunta tramite la scheda Sviluppo in Word 2010. Non vedo come il controllo legacy sarebbe apparso nell'equazione. –

Problemi correlati