I’m loading styles from a Word template and these include list styles and I’d like to create multiple lists.
According to the example, each new list requires a new ListStyle(). However when loading from document styles, there isn’t the opportunity to create a new ListStyle.
Here is my basic code, which doesn’t currently do what I want:
var doc = DocumentModel.Load(template);
var section = doc.Sections[0];
var sListNumber = doc.Styles.Single(s => s.Name == "List Number") as ParagraphStyle;
ListStyle tplStyle = sListNumber.ListFormat.Style;
var p1 = new Paragraph(doc, "First item.");
p1.ParagraphFormat = new ParagraphFormat { Style = sListNumber };
p1.ListFormat.Style = tplStyle;
p1.ListFormat.ListLevelNumber = 0;
var p2 = new Paragraph(doc, "New list.");
p2.ParagraphFormat = new ParagraphFormat { Style = sListNumber };
p2.ListFormat.Style = tplStyle;
p2.ListFormat.ListLevelNumber = 0;
section.Blocks.Add(p1);
section.Blocks.Add(p2);
doc.Save(path);
Setting .ListFormat.Style ensures that the output Word document has numId set (e.g. in document.xml <w:numPr><<w:numId w:val=“1”/></w:numPr>). And in this case each paragraph will get its own numId, which seems good.
However, both numIds then point to the same abstractNumId inside Word’s numbering.xml:
<w:num w:numId="1">
<w:abstractNumId w:val="0"/>
</w:num>
<w:num w:numId="2">
<w:abstractNumId w:val="0"/>
</w:num>
and so Word thinks they’re a single list, rather than two separate lists, and numbers them accordingly.
So how can I create multiple lists using the definitions from the document styles?
Hi,
However when loading from document styles, there isn’t the opportunity to create a new ListStyle.
Can you please explain what exactly do you mean by this?
Here is my basic code, which doesn’t currently do what I want:
Yes, the reason is that you’re using the same ListStyle.
Please check the “Lists” example, it’s creating two ListStyle, one is ListTemplateType.Bullet and another is ListTemplateType.NumberWithDot:
I hope this helps, let me know if you need anything else.
Regards,
Mario
How do I create a new ListStyle using existing style definitions?
My doc.Styles has all these definitions that I want to use, but new ListStyle() only allows me to pass ListTemplateType, and everything else looks like it has to be setup by copying things?
In my application I have two pieces of information for a paragraph:
- the paragraph style name to be used
- whether the paragraph is the start of a new list or not
So I lookup the style by name and assign it to the paragraph. I don’t know what the ListTemplateType is, and I don’t see how I can look it up from the style definition.
Hi,
Microsoft Word does not create a new ListStyle when you instruct it to restart list numbering. Instead, it overrides the start value in numbering.xml, like in the following snippet:
<w:num w:numId="2" w16cid:durableId="1130323833">
<w:abstractNumId w:val="0"/>
<w:lvlOverride w:ilvl="0">
<w:startOverride w:val="1"/>
</w:lvlOverride>
</w:num>
For example, I created the MyListStyle1.docx file using Microsoft Word. It has two lists whose items ultimately all point to the same abstractNum from the numbering.xml; however, the second list points to a different num from the numbering.xml that has a lvlOverride for level 0 with a startOverride set to 1.
The following code snippet loads that file, clears its content, and adds the same content using GemBox.Document API to show how to replicate actions done in MS Word:
var desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
var document = DocumentModel.Load(Path.Combine(desktop, "MyListStyle1.docx"));
var blocks = document.Sections[0].Blocks;
var prevousBlocks = blocks.ToArray();
blocks.Clear();
var myListStyle1 = (ParagraphStyle)document.Styles["MyListStyle1"];
blocks.Add(new Paragraph(document, "Item 1") { ParagraphFormat = { Style = myListStyle1 } });
blocks.Add(new Paragraph(document, "Item 2") { ParagraphFormat = { Style = myListStyle1 } });
blocks.Add(new Paragraph(document, "Line 3")
{
ListFormat = new ListFormat() { ListLevelNumber = 0, Style = (ListStyle)document.Styles["No List"] },
ParagraphFormat = { Style = myListStyle1, LeftIndentation = 0, SpecialIndentation = 0 }
});
var listFormat = new ListFormat()
{
ListLevelNumber = 0,
Style = myListStyle1.ListFormat.Style
};
listFormat.ListLevelFormat.StartAt = 1;
blocks.Add(new Paragraph(document, "Item 1 2")
{
ParagraphFormat = { Style = myListStyle1 },
ListFormat = listFormat.Clone()
});
blocks.Add(new Paragraph(document, "Item 2 2")
{
ParagraphFormat = { Style = myListStyle1 },
ListFormat = listFormat.Clone()
});
document.Save(Path.Combine(desktop, "MyListStyle1 out.docx"));
Here is a link to the output of this code snippet: MyListStyle1 out.docx.
Regards,
Stipo
What I’ve got from this is that creating a numbered list from a built-in list style should take the form
var listFormat = new ListFormat()
{
ListLevelNumber = 0, // or whatever the level is
Style = paragraphStyle.ListFormat.Style
};
listFormat.ListLevelFormat.StartAt = 1;
// and later
para.ListFormat = listFormat.Clone()
That seems to be working in my code now, so thank you 