2011-12-01 28 views
8

¿Cómo se puede obtener un control CheckBox integrado en un documento de Word usando OpenXML?Obtener un CheckBox en Word usando OpenXML

Pensarías que, o bien Paragraph.ControlPropertiesPart o Paragraph.Descendents() conseguirían algo, pero en cada caso recibo un tipo nulo devuelto.

Puedo recorrer el árbol del documento utilizando la estructura XML real, pero esto parece engorroso.

Sugerencias de bienvenida.

+0

¿Está utilizando un control de contenido de Check Box? – CoderDennis

Respuesta

10

El siguiente código muestra cómo enumerar todas las casillas de verificación en un documento de Word por usando el método Decendants<CheckBox>() en el cuerpo del docente.

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

para determinar el nombre de un elemento de entrada casilla dado que tiene que acceder a la propiedad Parent del CheckBox instancia y luego buscar el elemento FormFieldName (para asignar un nombre a una casilla de verificación utilizar el diálogo de propiedades de Microsoft Palabra).

La propiedad DefaultCheckBoxFormFieldStateVal tiene el estado predeterminado para la casilla de verificación. Además, la propiedad Val del elemento Checked contiene el estado verificado real de la instancia CheckBox. Tenga en cuenta que para Microsoft Word 2007, la propiedad Val es null si la casilla de verificación está marcada.

COMENZAR EDITAR

Me gustaría extender mi respuesta. De hecho, hay dos tipos de controles de casilla de verificación en la pestaña de desarrollador de MS Word: una casilla de verificación heredada y una casilla de control ActiveX. El código que se muestra arriba se puede usar para enumerar casillas de verificación heredadas en un documento de Word (consulte este article sobre cómo crear una casilla de verificación heredada).

Por lo que sé, no puede usar el SDK OpenXML para obtener/establecer valores para una casilla de verificación ActiveX. Sin embargo, puede enumerar los controles ActiveX utilizando el siguiente código:

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

Para determinar si o no un determinado Control es una casilla de verificación que tiene que ckeck el ID de clase de la Control. La identificación de clase de una casilla de verificación es {8BD21D40-EC42-11CE-9E0D-00AA006002F3}. Aquí está un ejemplo de código para obtener el identificador de clase (no sé si hay una manera más fácil ...):

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

FIN EDITAR

EDIT 2

No me di cuenta de que hay un nuevo control de casilla de verificación en Word 2010 (Gracias a Dennis Palmer).

Enumerar los nuevos en la casilla de verificación controla puede utilizar el siguiente código:

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

FIN EDIT 2

Esperanza, esto ayuda.

+0

Eso es lo que esperaba que funcionara, excepto que las tres casillas de verificación que he puesto en mi código todavía no se recogen. No puedo, por mi vida, descubrir lo que hice. A menos que haya diferentes tipos de casillas de verificación. Creé un documento de muestra e inserté las casillas de verificación del grupo Controles en la pestaña Desarrollador. –

+0

@ Phil.Wheeler: ¿Utiliza ActiveX Checkbox o el control de casilla heredado? Tenga en cuenta que el código anterior solo funciona con la casilla de verificación heredada. – Hans

+0

Diría que era el control ActiveX. Es un nuevo documento creado para el propósito y la casilla de verificación se agregó a través de la pestaña Desarrollador en Word 2010. No veo cómo el control heredado habría aparecido en la ecuación. –

Cuestiones relacionadas