2

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

我正在使用以下代码,但我的问题是在某些情况下我null在调用elem.SdtProperties.ChildElements.First<WP.Lock>().

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

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

1 回答 1

2

看来你的代码很好。在另一个有某个对象并且它返回 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 类,但这是经常发生的事情,这就是我这样做的原因。

希望能帮助到你

于 2012-09-17T15:57:52.603 回答