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を返す別のシナリオで同じ問題が発生しました。その時点でopenxmlsdkの何が問題になっているのかわかりませんが、私がどのように解決したかはわかります。

問題は基本的に、構造の深い特定のポイントで、Lockオブジェクトとして解釈されるべき要素があることを知っていますが、SDKはそれをOpenXmlElement(そのサブクラスのLockオブジェクトではない)としてのみ見ることができるためFirst<WP.Lock>()、 Lockオブジェクトを期待し、そこにあることは知っていますが、nullを取得するだけです。私がしていることは、すべてを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 に答える