AltChunk искажает элемент управления форматированным текстовым содержимым

Я использовал объект AltChunk для копирования данных из файла docx в элемент управления форматированным текстовым содержимым в другом файле. Копия работает нормально. Но теперь элемент управления содержимым нельзя преобразовать в SdtElement в OpenXml или в ContentControl в VSTO.

Это код, который я использовал

SdtElement sdtElement = destinationdocument.MainDocumentPart.Document.Body.Descendants<SdtElement>().Where(b => b.SdtProperties.GetFirstChild<Tag>() != null).FirstOrDefault();
string altChunkId = "AltChunkId" + Guid.NewGuid().ToString();
AlternativeFormatImportPart chunk = destinationdocument.MainDocumentPart.AddAlternativeFormatImportPart(AlternativeFormatImport    PartType.WordprocessingML, altChunkId);
chunk.FeedData(File.Open("sourceFile", FileMode.OpenOrCreate));
AltChunk altChunk = new AltChunk();
altChunk.Id = altChunkId;
sdtElement.RemoveAllChildren();
sdtElement.Append(altChunk);

с первого раза код работает нормально. Но при втором запуске первая строка выдает исключение невозможности создания. Та же проблема возникает при использовании VSTO на стороне клиента: объект ContentControl не может содержать элемент управления содержимым, в который был вставлен AltChunk. Каким-то образом эта процедура повреждает элемент управления форматированным текстовым содержимым.

Есть ли что-то, что я делаю неправильно? Или есть лучшая альтернатива?


person user1970213    schedule 12.02.2013    source источник
comment
Если вы включите в свой вопрос сведения об исключении, это поможет получить более целенаправленные ответы.   -  person Flowerking    schedule 12.02.2013


Ответы (1)


wordDocument.MainDocumentPart.Document.Body.Descendants<SdtElement>() возвращает IEnumerable<SdtElement>, и вы назначаете его SdtElemtnt. Попробуйте использовать var или фактический тип возвращаемого значения.

Обновление:

Ваш код рабочий. Что вы делаете неправильно, так это эта строка sdtElement.RemoveAllChildren();

Элемент sdt (элемент управления содержимым) содержит другие элементы, такие как sdtPr (свойства управления содержимым), sdtContent (фактическое содержимое внутри элемента управления содержимым) и т. д., как показано ниже, например.

 <w:sdt>
    <w:sdtPr>
        ...
    </w:sdtPr>
    <w:sdtContent>
      ....
    </w:sdtContent>
  </w:sdt>

Что делает ваш sdtElement.RemoveAllChildren();, так это удаляет все внутри элемента sdt и заменяет их как:

<w:sdt>
   <w:altChunk r:id="AltChunkIdffebf242-30b3-4905-bf39-fc0077be9474" />
</w:sdt>

Это заставляет вашу программу выдавать исключение при втором запуске, поскольку в строке destinationdocument.MainDocumentPart.Document.Body.Descendants<SdtElement>().Where(b => b.SdtProperties.GetFirstChild<Tag>() != null).FirstOrDefault(); ваш замененный элемент sdt документа не имеет SdtProperties, а также Tag или sdtContent.

Чтобы обойти эту проблему, попробуйте вставить блок altchunk в элемент содержимого управления содержимым (sdtContent) вместо элемента sdt, как показано ниже:

using (
    FileStream fileStream = File.Open("file.docx",
                                        FileMode.Open))
{
    chunk.FeedData(fileStream);
    AltChunk altChunk = new AltChunk();
    altChunk.Id = altChunkId;
    //sdtElement.RemoveAllChildren();
    sdtElement.Elements<SdtContentBlock>().FirstOrDefault().Append(altChunk); // This is going to add to the existing content.
}

Надеюсь это поможет!

person Flowerking    schedule 12.02.2013
comment
Я просто вставил часть кода. У него есть методы расширения LINQ, которые используют его для меня. Раньше работало нормально. Проблема возникает и в VSTO. Проблема определена. Управление контентом каким-то образом повреждено. - person user1970213; 12.02.2013
comment
Ваш код не показывает, что такое sdtElement и где вы вставляете altchunk в документ. Не могли бы вы обновить свой вопрос, чтобы включить эти детали. - person Flowerking; 12.02.2013