Pregunta

¿Cómo se consigue un mango de un control de casilla de verificación que está incrustado en un documento de Word usando OpenXML?

Pensaría que el párrafo.controlpropertiespart o el párrafo.descendents () lograría algo, pero en cada caso obtengo un tipo nulo devuelto.

Puedo atravesar el árbol de documentos utilizando la estructura XML real, pero esto parece engorroso.

Sugerencias bienvenidas.

¿Fue útil?

Solución

El siguiente código muestra cómo enumerar todas las casillas de verificación en un documento de Word utilizando el Decendants<CheckBox>() Método en el cuerpo 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());
    }
  }
}

Para determinar el nombre de un elemento de entrada de casilla de verificación dado, debe acceder alParent propiedad del CheckBox instancia y luego busque el FormFieldName Elemento (para asignar un nombre a una casilla de verificación Use el cuadro de diálogo Propiedades en Microsoft Word).

los DefaultCheckBoxFormFieldState Val La propiedad contiene el estado predeterminado para la casilla de verificación. Además el Val propiedad del Checked El elemento contiene el estado marcado real del CheckBox instancia. Nota, para Microsoft Word 2007, la propiedad Val es null Si se verifica la casilla de verificación.

Comenzar editar

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

Hasta donde yo 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 un dado o no Control es una casilla de verificación que tiene que ver la ID de clase del Control. La ID de clase de una casilla de verificación es {8BD21D40-EC42-11CE-9E0D-00AA006002F3}. Aquí hay una muestra de código para obtener la ID 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();

EDITAR EDITAR

Edición 2

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

Para enumerar esos nuevos controles de casilla de verificación, puede usar 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

Espero que esto ayude.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top