2012-09-17 58 views
2

我想以编程方式锁定所有内容控件,以便用户无法删除它们。Openxml - 锁定所有内容控件

我正在使用下面的代码,但我的问题是,在拨打elem.SdtProperties.ChildElements.First<WP.Lock>()时,我得到null

有人可以帮我完成下面提到的代码吗?

static void MakeContentControlsNonDeletable() 
     { 
      using (P.WordprocessingDocument wordDoc = 
       P.WordprocessingDocument.Open(@"c:\XYZ.docx", true)) 
      { 
       IEnumerable<WP.SdtElement> elements = 
        wordDoc.MainDocumentPart.Document.Descendants<WP.SdtElement>(); 

       foreach (WP.SdtElement elem in elements) 
       { 
        if (elem.SdtProperties != null) 
        { 
         WP.Lock l = elem.SdtProperties.ChildElements.First<WP.Lock>(); 

         if (l == null) 
         { 
          //Please help here 
          //Please help here 
          //Please help here 
          //Please help here 
         } 

         if (l.Val != WP.LockingValues.SdtContentLocked && l.Val != WP.LockingValues.SdtLocked) 
         { 
          Console.WriteLine("Unlock content element..."); 
          l.Val = WP.LockingValues.SdtLocked; 
         } 
        } 
       } 
      } 

回答

1

看来你的代码是好的。在另一个存在某个对象并且返回null的场景中,我遇到了同样的问题。我不知道那时openxml sdk有什么问题,但我可以告诉你我是如何解决这个问题的。

问题的根本在于,在结构深处的某些点,你知道有一个元素应该被解释为一个Lock对象,但是sdk只能将它看作OpenXmlElement(不是它的子类Lock对象),所以这就是为什么当你做First<WP.Lock>()你期待一个Lock对象,你知道它在那里,但你只是空。我所做的就是将所有内容都视为OpenXmlElement,而忘记了强大的打字。

static void MakeContentControlsNonDeletable() 
    { 
     using (P.WordprocessingDocument wordDoc = 
      P.WordprocessingDocument.Open(@"c:\XYZ.docx", true)) 
     { 
      IEnumerable<OpenXmlElement> elements = 
       wordDoc.MainDocumentPart.Document.Descendants<>(child => child.LocalName == "sdt"); 

      foreach (OpenXmlElement elem in elements) 
      { 
       if (elem.ChildElements.Any(child => child.LocalName == "sdtPr")) 
       { 
        OpenXmlElement sdtPr = elem.ChildElements.FirstOrDefault(child => child.LocalName == "sdtPr"); 
        OpenXmlElement l = sdtPr.ChildElements.FirstOrDefault(child => child.LocalName == "lock"); 

        if (l == null) //At this point if you have your lock object this isn't null 
        { 
         //Please help here 
         //Please help here 
         //Please help here 
        } 

        OpenXmlAttribute valAttribute = l.GetAttribute("val", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); 
        if (valAttribute != null) { 
         valAttribute = new OpenXmlAttribute(); 
        } 

        if (valAttribute.Value != "sdtContentLocked" && valAttribute.Value != "sdtLocked") 
        { 
         Console.WriteLine("Unlock content element..."); 
         valAttribute.Value = "sdtLocked"; 
        } 
       } 
      } 
     } 

我知道这是不是它应该是这样,我知道所有的对象应该是强类型到其各自的OPENXML SDK类,但在这个时候,发生了很多,这就是为什么我这样做。

希望它有帮助