Articles in this section
Category / Section

How to change tab leader of Table Of Contents in Word document?

10 mins read

Syncfusion Essential DocIO is a .NET Word library used to create, read, and edit Word documents programmatically without Microsoft Word or Interop dependencies. Using this library, you can add and modify the table of contents in a Word document using C# and VB.NET.

We can achieve this requirement by following these steps:

  1. Create a Word document.
  2. Append table of contents in the Word document.
  3. Update the table of contents in the Word document.
  4. Then, find the table of contents in the Word document by iterating through the document elements.
  5. Insert bookmark from start to end of the table of contents.
  6. Access the table of contents using the BookmarkNavigator.
  7. Iterate the bookmark content and change the tab leader for TOC paragraphs.
  8. Saves the Word document.

Steps to change the Tab leader for TOC paragraphs

  1. Create a new C# console application project.

Create Console application

  1. Install the Syncfusion.DocIO.WinForms NuGet package as a reference to your .NET Framework applications from Nuget.org.

Install DocIO NuGet Packages

  1. Include the following namespace.

C#

using Syncfusion.DocIO.DLS;

VB

Imports Syncfusion.DocIO.DLS
  1. The following code example shows how to change the tab leader for TOC paragraphs in the Word document.

C#

//Create a new Word document.
WordDocument document = new WordDocument();
//Add the section into the Word document.
IWSection section = document.AddSection();
string paraText = "AdventureWorks Cycles, the fictitious company on which the AdventureWorks sample databases are based, is a large, multinational manufacturing company.";
//Add the paragraph into the created section.
IWParagraph paragraph = section.AddParagraph();
//Append the TOC field with LowerHeadingLevel and UpperHeadingLevel to determine the TOC entries.
paragraph.AppendTOC(1, 3);
//Add the section into the Word document.
section = document.AddSection();
//Add the paragraph into the created section.
paragraph = section.AddParagraph();
//Add the text for the headings.
paragraph.AppendText("First Chapter");
//Set a built-in heading style.
paragraph.ApplyStyle(BuiltinStyle.Heading1);
//Add the text into the paragraph.
section.AddParagraph().AppendText(paraText);
//Add the section into the Word document.
section = document.AddSection();
//Add the paragraph into the created section.
paragraph = section.AddParagraph();
//Add the text for the headings
paragraph.AppendText("Second Chapter");
//Set a built-in heading style.
paragraph.ApplyStyle(BuiltinStyle.Heading2);
//Add the text into the paragraph.
section.AddParagraph().AppendText(paraText);
//Add the section into the Word document.
section = document.AddSection();
//Add the paragraph into the created section.
paragraph = section.AddParagraph();
//Add the text into the headings.
paragraph.AppendText("Third Chapter");
//Set a built-in heading style.
paragraph.ApplyStyle(BuiltinStyle.Heading3);
//Add the text into the paragraph.
section.AddParagraph().AppendText(paraText);
//Update the table of contents.
document.UpdateTableOfContents();
//Find the TOC from a Word document.
TableOfContent toc = FindTableOfContent(document);
 
//Change tab leader for table of contents in the Word document.
if (toc != null)
ChangeTabLeaderForTableOfContents(toc, TabLeader.Hyphenated);
 
//Save and close the Word document.
document.Save("Result.docx");
document.Close();
 

VB

'Create a new Word document.
Dim document As WordDocument =New WordDocument()
'Add the section into the Word document.
Dim section As IWSection = document.AddSection()
Dim paraText As String = "AdventureWorks Cycles, the fictitious company on which the AdventureWorks sample databases are based, is a large, multinational manufacturing company."
'Add the paragraph into the created section.
Dim paragraph As IWParagraph = section.AddParagraph()
'Append the TOC field with LowerHeadingLevel and UpperHeadingLevel to determine the TOC entries.
paragraph.AppendTOC(1, 3)
'Add the section into the Word document.
section = document.AddSection()
'Add the paragraph into the created section.
paragraph = section.AddParagraph()
'Add the text for the headings.
paragraph.AppendText("First Chapter")
'Set a built-in heading style.
paragraph.ApplyStyle(BuiltinStyle.Heading1)
'Add the text into the paragraph.
section.AddParagraph().AppendText(paraText)
'Add the section into the Word document.
section = document.AddSection()
'Add the paragraph into the created section.
paragraph = section.AddParagraph()
'Add the text for the headings.
paragraph.AppendText("Second Chapter")
'Set a built-in heading style.
paragraph.ApplyStyle(BuiltinStyle.Heading2)
'Add the text into the paragraph.
section.AddParagraph().AppendText(paraText)
'Add the section into the Word document.
section = document.AddSection()
'Add the paragraph into the created section.
paragraph = section.AddParagraph()
'Add the text into the headings.
paragraph.AppendText("Third Chapter")
'Set a built-in heading style.
paragraph.ApplyStyle(BuiltinStyle.Heading3)
'Add the text into the paragraph.
section.AddParagraph().AppendText(paraText)
'Update the table of contents.
document.UpdateTableOfContents()
'Find the TOC from a Word document.
Dim toc As TableOfContent = Program.FindTableOfContent(document)
'Change tab leader for table of contents in a Word document.
If toc IsNot Nothing Then ChangeTabLeaderForTableOfContents(toc, TabLeader.Hyphenated)
'Saves and closes the Word document.
document.Save("Result.docx")
document.Close()
  1. The following code example provides supporting methods for the above code.

5.1 Find table of contents from the Word document by iterating through the document elements.

C#

/// <summary>
/// Finds the table of content from a Word document by iterating its elements.
/// </summary>
private static TableOfContent FindTableOfContent(WordDocument document)
{
foreach (var item in document.Visit())
{
if (item is TableOfContent)
return item as TableOfContent;
}
return null;
}

VB

'''<summary>
'''Finds the table of content from a Word document by iterating its elements.
''' </summary>
Private Shared Function FindTableOfContent(ByVal document As WordDocument) As TableOfContent
For Each item In document.Visit()
If TypeOf item Is TableOfContent Then Return TryCast(item, TableOfContent)
Next
 
Return Nothing
End Function
 

5.2 Insert bookmark which covers TOC of the Word document. Then, access the bookmark content using the BookmarkNavigator and change the table leader for the TOC paragraphs.

C#

/// <summary>
/// Change tab leader for table of contents in the Word document.
/// </summary>
private static void ChangeTabLeaderForTableOfContents(TableOfContent toc, TabLeader tabLeader)
{
//Insert the bookmark start before the TOC instance.
BookmarkStart bkmkStart = new BookmarkStart(toc.Document, "tableOfContent");
toc.OwnerParagraph.Items.Insert(toc.OwnerParagraph.Items.IndexOf(toc), bkmkStart);
 
Entity lastItem = FindLastTOCItem(toc);
 
//Insert the bookmark end to next of TOC last item.
BookmarkEnd bkmkEnd = new BookmarkEnd(toc.Document, "tableOfContent");
WParagraph paragraph = lastItem.Owner as WParagraph;
paragraph.Items.Insert(paragraph.Items.IndexOf(lastItem) + 1, bkmkEnd);
 
//Create the bookmark navigator instance to access the bookmark.
BookmarksNavigator bookmarkNavigator = new BookmarksNavigator(toc.Document);
//Move the virtual cursor to the location before the end of the bookmark "tableOfContent."
bookmarkNavigator.MoveToBookmark("tableOfContent");
//Get the bookmark content.
TextBodyPart part = bookmarkNavigator.GetBookmarkContent();
 
//Iterate the items from the bookmark to change the spacing in the table of content.
for (int i = 0; i < part.BodyItems.Count; i++)
{
paragraph = part.BodyItems[i] as WParagraph;
//Set the tab leader as none.
if (paragraph.ParagraphFormat.Tabs.Count != 0)
paragraph.ParagraphFormat.Tabs[0].TabLeader = tabLeader;
}
 
//Remove the bookmark which we add to get the paragraphs in the table of contents.
Bookmark bookmark = toc.Document.Bookmarks.FindByName("tableOfContent");
toc.Document.Bookmarks.Remove(bookmark);
 
}
 
/// <summary>
/// Finds the last TOC item.
/// </summary>
private static Entity FindLastTOCItem(TableOfContent toc)
{
int tocIndex = toc.OwnerParagraph.Items.IndexOf(toc);
//TOC may contains nested fields and each fields has its owner field end mark. 
//To indentify the TOC Field end mark (WFieldMark instance) used the stack.
Stack<Entity> fieldStack = new Stack<Entity>();
fieldStack.Push(toc);
 
//Find whether the TOC end item is exist in a same paragraph.
for (int i = tocIndex + 1; i < toc.OwnerParagraph.Items.Count; i++)
{
Entity item = toc.OwnerParagraph.Items[i];
 
if (item is WField)
fieldStack.Push(item);
else if (item is WFieldMark && (item as WFieldMark).Type == FieldMarkType.FieldEnd)
{
if (fieldStack.Count == 1)
{
fieldStack.Clear();
return item;
}
else
fieldStack.Pop();
}
 
}
 
return FindLastItemInTextBody(toc, fieldStack);
}
/// <summary>
/// Find the last TOC item from consequence text body items.
/// </summary>
private static Entity FindLastItemInTextBody(TableOfContent toc, Stack<Entity> fieldStack)
{
WTextBody tBody = toc.OwnerParagraph.OwnerTextBody;
 
for (int i = tBody.ChildEntities.IndexOf(toc.OwnerParagraph) + 1; i < tBody.ChildEntities.Count; i++)
{
WParagraph paragraph = tBody.ChildEntities[i] as WParagraph;
 
foreach (Entity item in paragraph.Items)
{
if (item is WField)
fieldStack.Push(item);
else if (item is WFieldMark && (item as WFieldMark).Type == FieldMarkType.FieldEnd)
{
if (fieldStack.Count == 1)
{
fieldStack.Clear();
return item;
}
else
fieldStack.Pop();
}
}
}
return null;
}
 

VB

''' <summary>
''' Change tab leader for the table of contents in the Word document.
''' </summary>
Private Shared Sub ChangeTabLeaderForTableOfContents(ByVal toc As TableOfContent, ByVal tabLeader As TabLeader)
'Insert the bookmark start before the TOC instance.
Dim bkmkStart As BookmarkStart = New BookmarkStart(toc.Document, "tableOfContent")
toc.OwnerParagraph.Items.Insert(toc.OwnerParagraph.Items.IndexOf(toc), bkmkStart)
Dim lastItem As Entity = SurroundingClass.FindLastTOCItem(toc)
 
'Insert the bookmark end to next of TOC last item.
Dim bkmkEnd As BookmarkEnd = New BookmarkEnd(toc.Document, "tableOfContent")
Dim paragraph As WParagraph = TryCast(lastItem.Owner, WParagraph)
paragraph.Items.Insert(paragraph.Items.IndexOf(lastItem) + 1, bkmkEnd)
 
'Create the bookmark navigator instance to access the bookmark.
Dim bookmarkNavigator As BookmarksNavigator = New BookmarksNavigator(toc.Document)
'Move the virtual cursor to the location before the end of the bookmark "tableOfContent."
bookmarkNavigator.MoveToBookmark("tableOfContent")
'Get the bookmark content.
Dim part As TextBodyPart = bookmarkNavigator.GetBookmarkContent()
 
'Iterate the items from the bookmark to change the spacing in the table of content.
For i As Integer = 0 To part.BodyItems.Count - 1
paragraph = TryCast(part.BodyItems(i), WParagraph)
'Sets the tab leader as none.
If paragraph.ParagraphFormat.Tabs.Count <> 0 Then paragraph.ParagraphFormat.Tabs(0).TabLeader = tabLeader
Next
 
'Remove the bookmark which we add to get the paragraphs in the table of contents.
Dim bookmark As Bookmark = toc.Document.Bookmarks.FindByName("tableOfContent")
toc.Document.Bookmarks.Remove(bookmark)
End Sub
 
''' <summary>
''' Find the last TOC item.
''' </summary>
Private Shared Function FindLastTOCItem(ByVal toc As TableOfContent) As Entity
Dim tocIndex As Integer = toc.OwnerParagraph.Items.IndexOf(toc)
'TOC may contains the nested fields and each fields has its owner field end mark. 
'To indentify the TOC Field end mark (WFieldMark instance) used the stack.
Dim fieldStack As Stack(Of Entity) = New Stack(Of Entity)()
fieldStack.Push(toc)
 
'Find whether TOC end item is exist in a same paragraph.
For i As Integer = tocIndex + 1 To toc.OwnerParagraph.Items.Count - 1
Dim item As Entity = toc.OwnerParagraph.Items(i)
 
If TypeOf item Is WField Then
fieldStack.Push(item)
ElseIf TypeOf item Is WFieldMark AndAlso TryCast(item, WFieldMark).Type Is FieldMarkType.FieldEnd Then
 
If fieldStack.Count = 1 Then
fieldStack.Clear()
Return item
Else
fieldStack.Pop()
End If
End If
Next
 
Return SurroundingClass.FindLastItemInTextBody(toc, fieldStack)
End Function
 
''' <summary>
''' Find the last TOC item from consequence text body items.
''' </summary>
Private Shared Function FindLastItemInTextBody(ByVal toc As TableOfContent, ByVal fieldStack As Stack(Of Entity)) As Entity
Dim tBody As WTextBody = toc.OwnerParagraph.OwnerTextBody
 
For i As Integer = tBody.ChildEntities.IndexOf(toc.OwnerParagraph) + 1 To tBody.ChildEntities.Count - 1
Dim paragraph As WParagraph = TryCast(tBody.ChildEntities(i), WParagraph)
 
For Each item As Entity In paragraph.Items
 
If TypeOf item Is WField Then
fieldStack.Push(item)
ElseIf TypeOf item Is WFieldMark AndAlso TryCast(item, WFieldMark).Type Is FieldMarkType.FieldEnd Then
 
If fieldStack.Count = 1 Then
fieldStack.Clear()
Return item
Else
fieldStack.Pop()
End If
End If
Next
Next
 
Return Nothing
End Function
 
  1. The following code example provides an helper class to find the table of contents in the Word document.

C#

/// <summary>
/// DocIO extension class.
/// </summary>
public static class DocIOExtensions
{
public static IEnumerable<IEntity> Visit(this ICompositeEntity entity)
{
var entities = new Stack<IEntity>(new IEntity[] { entity });
while (entities.Count > 0)
{
var e = entities.Pop();
yield return e;
if (e is ICompositeEntity)
{
foreach (IEntity childEntity in ((ICompositeEntity)e).ChildEntities)
{
entities.Push(childEntity);
}
}
}
}
}

VB

''' <summary>
''' DocIO extension class.
''' </summary>
 
Public Module DocIOExtensions
<Extension()>
 Public Iterator Function Visit(ByVal entity As ICompositeEntity) As IEnumerable(Of IEntity)
Dim entities = New Stack(Of IEntity)(New IEntity() {entity})
 
While entities.Count > 0
Dim e = entities.Pop()
Yield e
 
If TypeOf e Is ICompositeEntity Then
 
For Each childEntity As IEntity In CType(e, ICompositeEntity).ChildEntities
entities.Push(childEntity)
Next
End If
End While
End Function
End Module
 
 

 

A complete working example of how to change tab leader for a table of contents in a Word document using C# can be downloaded from the change tab leader of TOC.zip.

By executing the program, you can get a Word document as follows.

Output Word document

You can refer to our documentation to know more about working with the table of contents in a Word document using the Syncfusion .NET Word library (Essential DocIO).

Take a moment to peruse the documentation. You can find basic Word document processing options along with features like mail merge, merge, and split documents, find and replace text in the Word document, protect the Word documents, and most importantly PDF and Image conversions with code examples.

Explore more about a rich set of Syncfusion Word Framework features.

Did you find this information helpful?
Yes
No
Help us improve this page
Please provide feedback or comments
Comments (0)
Please sign in to leave a comment
Access denied
Access denied