Get page to insert into text

Hello,
I’d like to insert the page numer inside a Run/Paragraph. Something like this:
grafik

But I cant seem to get it from the FieldType.Page, nor adjust a TableOfEntries to just return/display the page number.

Is something like that possible or should I try a different approach?

Thanks for any help!

You cannot insert a page number inside a Run, but you can insert it inside a Paragraph.
Basically, you need to add a Field element inside the Paragraph.Inlines collection.

What do you mean by this?
Do you want to remove the tabs from TOC entries or something else?

If that’s the case, then try this:

new TableOfEntries(document, FieldType.TOC, @"\o ""1-3"" \h \u \p "" """)

I hope this helps.

What do you mean by this?
Do you want to remove the tabs from TOC entries or something else?

My idea was to just have the page number, so I wouldnt have to insert the Field with page afterwards, since the only option I came up with was to use String.Replace, which doesnt work with Fields

For more context, this is how I generate my frontpage rn

public static List<TextBox> GenerateFrontPageContent(DocumentModel document, List<string> bps)
        {
            var frontPageContent = new List<TextBox>();
            int textBoxIndex = 1;
            var height = 0.0;

            if (bps.Count > 16)
            {
                height = 300;
            }
            else
            {
                height = bps.Count * 40;
            }

            var textBox = new TextBox(
                document, 
                Layout.Floating(
                    new HorizontalPosition(80, LengthUnit.Point, HorizontalPositionAnchor.Page),
                    new VerticalPosition(370, LengthUnit.Point, VerticalPositionAnchor.Page),
                    new Size(150, height)), 
                ShapeType.RoundedRectangle);
            textBox.AdjustValues.Add("adj", 4600);
            textBox.Fill.SetSolid(IdrColors.DarkBlue);

            foreach (var bp in bps.Select((value, i) => new {value, i}))
            {
                textBox.Blocks.Add(new Paragraph(
                    document,
                    new Hyperlink(document, bp.value, 
                            new Run(document, $"{bp.i + 1}. {bp.value}") 
                            {CharacterFormat = {FontColor = Color.White, Size = 8, Bold = true}})
                        {IsBookmarkLink = true}));

                //number is dependent on fontsize, adjust if font is adjusted
                if (bp.i % 16 == 0 && bp.i != 0)
                {
                    frontPageContent.Add(textBox);
                    
                    textBox = new TextBox(
                        document, 
                        Layout.Floating(
                            new HorizontalPosition(250 * textBoxIndex, LengthUnit.Point, HorizontalPositionAnchor.Page),
                            new VerticalPosition(380, LengthUnit.Point, VerticalPositionAnchor.Page),
                            new Size(150, (bps.Count - bp.i) * 50)), 
                        ShapeType.RoundedRectangle);
                    textBox.AdjustValues.Add("adj", 4600);
                    textBox.Fill.SetSolid(IdrColors.DarkBlue);

                    textBoxIndex++;
                }
            }

            frontPageContent.Add(textBox);

            return frontPageContent;
        }

Since I need to create multiple textboxes, in case one would be too big for my page I need to iterate through multiples, which I’m not able to do with a TableOfEntries, to my understanding

I’m not sure what you’re trying to do.

Can you send us a DOCX file that you’re currently generating and a DOCX file that will show exactly what you would like to get?

I’ll compare the two documents and provide a snippet code that shows what you need to get the desired result.

I’m trying to generate a pdf with a ToC like this (preferably with p. instead of “…”):
grafik

Where the ToC is split onto multiple Textboxes when a singular one is too small.
I couldnt paste the DOCX, sorry

Try this:

public static List<TextBox> GenerateFrontPageContent(DocumentModel document, List<string> bps)
{
    var frontPageContent = new List<TextBox>();
    int textBoxIndex = 1;
    var height = 0.0;
    if (bps.Count > 16)
    {
        height = 300;
    }
    else
    {
        height = bps.Count * 40;
    }

    var textBox = new TextBox(document,
        Layout.Floating(
            new HorizontalPosition(80, LengthUnit.Point, HorizontalPositionAnchor.Page),
            new VerticalPosition(370, LengthUnit.Point, VerticalPositionAnchor.Page),
            new Size(150, height)),
        ShapeType.RoundedRectangle);
    textBox.AdjustValues.Add("adj", 4600);
    textBox.Fill.SetSolid(Color.DarkBlue);

    foreach (var bp in bps.Select((value, i) => new { value, i }))
    {
        string bookmarkName = $"_item_bookmark_{bp.i + 1}";
        textBox.Blocks.Add(
            new Paragraph(document,
                new Hyperlink(document, bookmarkName,
                    new Run(document, $"{bp.i + 1}. {bp.value} p.")
                    { CharacterFormat = { FontColor = Color.White, Size = 8, Bold = true } },
                    new Field(document, FieldType.PageRef, bookmarkName)
                    { CharacterFormat = { FontColor = Color.White, Size = 8, Bold = true } })
            { IsBookmarkLink = true }));

        //number is dependent on fontsize, adjust if font is adjusted
        if (bp.i % 12 == 0 && bp.i != 0)
        {
            frontPageContent.Add(textBox);
            textBox = new TextBox(document,
                Layout.Floating(
                    new HorizontalPosition(250 * textBoxIndex, LengthUnit.Point, HorizontalPositionAnchor.Page),
                    new VerticalPosition(380, LengthUnit.Point, VerticalPositionAnchor.Page),
                    new Size(150, (bps.Count - bp.i) * 50)),
                ShapeType.RoundedRectangle);
            textBox.AdjustValues.Add("adj", 4600);
            textBox.Fill.SetSolid(Color.DarkBlue);

            textBoxIndex++;
        }
    }

    frontPageContent.Add(textBox);
    return frontPageContent;
}

Notice that I’m adding PageRef fields, those fields will result in desired page numbers.

Now to achieve that we’ll need to add the bookmarks to which those PageRef fields reference.

For that you can use something like this:

static void Draw()
{
    var document = new DocumentModel();
    var section = new Section(document);
    document.Sections.Add(section);

    var bps = new List<string>()
    {
        "item1", "item2", "item3",
        "item4", "item5", "item6",
        "item7", "item8", "item9",
        "item10", "item11", "item12",
        "item13", "item14", "item15",
        "item16", "item17", "item18",
    };

    var frontPageContent = GenerateFrontPageContent(document, bps);
    section.Blocks.Add(new Paragraph(document, frontPageContent));

    section.Blocks.Add(new Paragraph(document,
        new SpecialCharacter(document, SpecialCharacterType.PageBreak)));

    var random = new Random();
    foreach (var bp in bps.Select((value, i) => new { value, i }))
    {
        string bookmarkName = $"_item_bookmark_{bp.i+1}";
        section.Blocks.Add(new Paragraph(document,
            new BookmarkStart(document, bookmarkName),
            new Run(document, bp.value),
            new BookmarkEnd(document, bookmarkName)));

        if (bp.i % 2 == 0 && random.NextDouble() >= 0.5)
            section.Blocks.Add(new Paragraph(document,
                new SpecialCharacter(document, SpecialCharacterType.PageBreak)));
    }

    document.GetPaginator(new PaginatorOptions() { UpdateFields = true });
    document.Save("test.docx");
}

I’m adding those items and their corresponding bookmarks, also at random I’m placing page breaks between them.

Last, the GetPaginator method call with the enabled PaginatorOptions.UpdateFields is the one that is updating those PageRef fields.

This call is required when saving to DOCX format, but it is not required when saving to PDF because this update will already be done in that case.

I hope this helps.