使用OpenXML在Word中获取复选框

问题描述:

如何获取使用OpenXML嵌入Word文档的CheckBox控件的句柄?使用OpenXML在Word中获取复选框

你会认为Paragraph.ControlPropertiesPart或Paragraph.Descendents()会实现某些功能,但在每一种情况下,我都会返回一个空类型。

我可以使用实际的XML结构遍历文档树,但这看起来很麻烦。

建议欢迎。

+0

您使用复选框内容控件吗? – CoderDennis

下面的代码显示了如何使用Decendants<CheckBox>()方法在docuement的主体上枚举word文档中的所有复选框 。

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

要确定你要访问CheckBox实例的 Parent属性,然后搜索FormFieldName元素(指定名称的复选框使用属性对话框中微软给定的复选框输入元素的name字)。

DefaultCheckBoxFormFieldStateVal属性保留该复选框的默认状态。 此外,Checked元素的Val属性保存CheckBox实例的实际选中状态 。请注意,对于Microsoft Word 2007,Val属性为null,如果选中 复选框。

BEGIN编辑

我想延长我的答案。实际上,MS Word开发人员选项卡上有两种复选框控件 - 旧复选框和ActiveX控件复选框。上面显示的代码可用于枚举Word文档中的旧复选框(有关如何创建旧复选框,请参阅此article)。

据我所知,你不能使用OpenXML SDK来获取/设置ActiveX复选框的值。 但是可以用下面的代码枚举ActiveX控件:

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

为了确定一个给定的Control是否是你必须ckeck的Control的类ID的复选框。复选框的类别ID是{8BD21D40-EC42-11CE-9E0D-00AA006002F3}。 下面是一个代码示例来获取类ID(我不知道是否有更简单的方法...):

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

编辑完

EDIT 2

我没有意识到在Word 2010中有一个新的复选框控件(感谢Dennis Palmer)。

要列举这些新的复选框控件,你可以使用下面的代码:

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

END EDIT 2

希望,这会有所帮助。

+0

这就是我所期望的工作,除了我放在代码中的三个复选框仍然没有被拾取。我不能为我的生活找出我所做的。除非有不同类型的复选框。我已经创建了一个示例文档,并从Developer选项卡的Controls组中插入了复选框。 –

+0

@ Phil.Wheeler:您是否使用ActiveX复选框或旧复选框控件?请注意,上面的代码仅适用于旧版复选框。 – Hans

+0

我会说这是ActiveX控件。这是一个全新的文档,目的是通过Word 2010中的开发人员选项卡添加复选框。我没有看到传统控件甚至会出现在公式中。 –