Search code examples
c#ms-wordopenxmldocxword-contentcontrol

Remove Content Control form WordprocessingDocument without losing place


I'm removing a Content Control from a Word document with this code (posted on link)

 MainDocumentPart mainPart = _wordDocument.MainDocumentPart;
 List<SdtBlock> sdtList = mainPart.Document.Descendants<SdtBlock>).ToList();

  foreach (SdtBlock sdt in sdtList)
  {
    OpenXmlElement sdtc = sdt.GetFirstChild<SdtContentBlock>();
    OpenXmlElement parent = sdt.Parent;
    OpenXmlElementList elements = sdtc.ChildElements;  

    var mySdtc = new SdtContentBlock(sdtc.OuterXml);         
    foreach (OpenXmlElement elem in elements)
    {
       parent.Append((OpenXmlElement)elem.Clone());                   
    }       
    sdt.Remove();
  }

All works fine but the text after the delete operation loses the place in which it was before the operation. I know SimplifyMarkup from openxmlpowertools but I cant use it. Thx for any suggestions


Solution

  • You're pulling the rug out from under your own feet.

    foreach (SdtBlock sdt in sdtList)
    {
        sdt.Remove();
        // Now what?
    }
    

    At the comment point (although it's actually at the bracket), sdt doesn't exist, so how do you move to the next when you don't know where you are?

    The solution is to work backwards, or make a list and delete them at the end. Working backwards uses a count, which still exists when you remove the element, so it can still iterate.

    foreach (int i = sdtList.Count() -1; i > 0; i--)
    {
        var sdt = sdtList[i];
        OpenXmlElement sdtc = sdt.GetFirstChild<SdtContentBlock>();
        OpenXmlElement parent = sdt.Parent;
        OpenXmlElementList elements = sdtc.ChildElements;  
    
        var mySdtc = new SdtContentBlock(sdtc.OuterXml);         
        foreach (OpenXmlElement elem in elements)
        {
            parent.Append((OpenXmlElement)elem.Clone());                   
        }       
        sdtList.Remove(sdtList[i]);
    }