I’m running into an issue with the Table of Contents field, and updating it via the UpdateFields method.
We create a number of smaller documents that are then compiled into one comprehensive document. The TC fields are created simply and can contain formatting including bolded text, which I correctly inserted into the TC entry via code like this:
string tocEntry = string.Format("TC \"{0}\" \\l " + level, entry);
Field field = builder.InsertField(FieldType.FieldTOCEntry, false);
//remove the run curently in the field
field.End.PreviousSibling.Remove();
//move to the field after (which should put the cursor before the field end node)
builder.MoveTo(field.End);
//insert the Toc as Html
builder.InsertHtml(tocEntry, true);
Which allows me to put Html into the TC fields (a feature that would be useful in the future)
The TOC that we use for them has \f \h \z flags on it, and that’s it. It’s created like this:
Field toc = builder.InsertTableOfContents("\\f \\z \\h");
//update the ToC fields
builder.Document.UpdateFields();
which causes the issue. Without the \h flag there is no issue, and the ToC generates with formatting. When adding the flag, the formatting disappears.
I did manage to find a work around. By inserting the ToC with just the \f and \z flags, calling update fields, and then iterating over every paragraph in the ToC and expanding the PAGEREF field that surrounds the number to surround the entire line instead, I get an identical effect. And then, in order to allow for the document to update the field in the correct way, I track the ToC start and manually add in the \h flag to the run that’s the field code, making sure not to call update fields before I save.
//expand all page references to the entire line in the ToC
NodeCollection tocParagraphs = tocSection.Body.GetChildNodes(NodeType.Paragraph, false);
Run tocRun = null;
for (int i = 0; i < tocParagraphs.Count; i++)
{
var para = (Paragraph) tocParagraphs[i];
List<Node> childNodeList = para.ChildNodes.Cast<Node>().ToList();
if (childNodeList.Any(p => p.NodeType == NodeType.FieldStart))
{
Node firstEntryRun = childNodeList[0];
//if this is the first paragraph, it will also include the beginning of the
if (firstEntryRun.NodeType == NodeType.FieldStart && ((FieldStart) firstEntryRun).FieldType == FieldType.FieldTOC)
{
tocRun = (Run) childNodeList[1];
firstEntryRun = childNodeList[3];
}
Node pageRefFieldStart = childNodeList
.First(p => p.NodeType == NodeType.FieldStart && ((FieldStart) p).FieldType == FieldType.FieldPageRef);
var pageRefFields = new List<Node>()
{
pageRefFieldStart,
pageRefFieldStart.NextSibling,
pageRefFieldStart.NextSibling.NextSibling
};
pageRefFields.ForEach(p =>
{
p.ParentNode.InsertBefore(p, firstEntryRun);
});
}
}
if (tocRun != null)
tocRun.Text = tocRun.Text + " \\h";