Diese Seite kann automatisch übersetzten Text enthalten.

Größe, Position und Rendering von Containern

Inhalt ist der wichtigste Teil eines Dokuments. Daran besteht kein Zweifel. Ein weiterer entscheidender Teil ist die Formatierung, die eine klare, professionelle und wirksame Kommunikation schafft. Ein korrekt formatiertes Dokument ist optisch ansprechend, gut lesbar und leicht zu navigieren.

Möglicherweise wissen Sie bereits, wie Sie Inhalt mithilfe von Containern organisieren. Und wie Sie ihnen eine Hintergrundfarbe zuweisen. Dieser Artikel beschreibt, wie Sie Größe und Position für Container angeben. Er behandelt auch erweiterte Funktionen wie das bedingte Rendering von Inhalt. Außerdem enthält er Informationen zur Unterstützung von Inhaltsrichtungen von rechts nach links.

Positionierung von Containern

Die LayoutContainer Klasse bietet alles, was Sie benötigen, um Ihre Container professionell anzuordnen. Durch das Anwenden von Innenabstand und Ausrichtung können Sie ein Dokument erstellen, das bei seinen Benutzern einen positiven Eindruck hinterlässt.

Dieser Artikel ist Teil einer Serie über Layout API zur PDF-Generierung. Wenn Sie mit der API noch nicht vertraut sind, lesen Sie zuerst den Teil Erste Schritte mit Layout API.

Größe

Standardmäßig belegen Container die kleinste Fläche, die für ihren Inhalt erforderlich ist. Anders gesagt entspricht die Größe des Containers der intrinsischen Größe seines Inhalts.

Die intrinsische Größe eines Bildes wird durch die Abmessungen der Bilddatei selbst bestimmt. Die intrinsische Größe eines Textspan ist die Größe der Fläche, die alle Glyphen im Span abdeckt.

Die Größe eines zusammengesetzten Containers wie Column oder Table hängt von der Größe der Containerteile ab.

Width & Height

Es ist möglich, eine exakte Breite und Höhe eines Containers mithilfe der Width- und Height-Methoden anzugeben. Das ist für Platzhalter-Container sehr praktisch.

Eine exakte Größe eignet sich auch gut für Bilder. Das liegt daran, dass Layout API sie je nach ImageContentMode an den Container anpasst oder ihn ausfüllt.

Bei exakten Größen für zusammengesetzte Container und Container mit Text sollten Sie vorsichtig sein. Sie erhalten eine LayoutException, wenn sich Inhalt nicht in die bereitgestellte Größe einpassen lässt.

Es gibt Fälle, in denen Sie nur eine Einschränkung für Breite oder Höhe festlegen möchten. Sie können Einschränkungen mithilfe der MinWidth-, MinHeight-, MaxWidth- und MaxHeight-Methoden festlegen.

Beachten Sie, dass die Bibliothek eine LayoutException auslöst, wenn sich die Einschränkungen nicht erfüllen lassen.

Extend

Ein Container kann sich erweitern, um den maximal verfügbaren Platz einzunehmen. Das ist nützlich, wenn Sie keine exakte Größe oder Größenbeschränkungen kennen.

Verwenden Sie die ExtendHorizontal-Methode, wenn der Container nur in horizontaler Richtung den gesamten verfügbaren Platz einnehmen soll. Die ExtendVertical-Methode ist nützlich, wenn Sie den Container nur in vertikaler Richtung erweitern möchten. Die Extend-Methode bewirkt, dass der Container in beiden Richtungen den gesamten verfügbaren Platz einnimmt.

var gray = new PdfGrayColor(75);
var text = "Content goes here";
var size = new PdfSize(150, 50);

PdfDocumentBuilder.Create().Generate("positioning-extend.pdf", doc =>
{
    for (int i = 0; i < 4; i++)
    {
        doc.Pages(page =>
        {
            page.Size(size);
            page.Content().Row(r =>
            {
                var container = r.AutoItem().Background(gray);
                switch (i)
                {
                    case 0:
                        container.Text(text);
                        break;

                    case 1:
                        container.ExtendHorizontal().Text(text);
                        break;

                    case 2:
                        container.ExtendVertical().Text(text);
                        break;

                    case 3:
                        container.Extend().Text(text);
                        break;
                }
            });
        });
    }
});

Das Ergebnis des obigen Codes finden Sie in positioning-extend.pdf. Wie Sie sehen, enthält jede der vier Seiten denselben Text auf grauem Hintergrund. Aber die Größe des Containers ist auf jeder Seite unterschiedlich.

MinimalBox

Die LayoutContainer-Klasse bietet die MinimalBox-Methode. Sie ist gewissermaßen das Gegenteil der Extend-Methoden. Die MinimalBox-Methode erzeugt verschachtelte Container, die für den Inhalt nur den minimal erforderlichen Platz verwenden.

var gray = new PdfGrayColor(75);
var size = new PdfSize(150, 50);

PdfDocumentBuilder.Create().Generate("positioning-minimalbox.pdf", doc =>
{
    doc.Pages(page =>
    {
        page.Size(size);
        page.Content().MinimalBox().Background(gray).Text("I don't want more space");
    });

    doc.Pages(page =>
    {
        page.Size(size);
        page.Content().Background(gray).Text("I'll take everything");
    });
});

Das Ergebnis des obigen Codes finden Sie in positioning-minimalbox.pdf. Aufgrund des Aufrufs MinimalBox belegt der Text auf der ersten Seite nur den erforderlichen Platz. Auf der zweiten Seite füllt der Text die gesamte Seite aus.

Scale

Es ist möglich, beliebigen Inhalt in einem Container zu skalieren. Die Scale-Methode wirkt sich auf Inhalt sowohl in horizontaler als auch in vertikaler Richtung aus. Verwenden Sie die ScaleHorizontal- oder ScaleVertical-Methode, um Inhalt nur in einer Richtung zu ändern. Die beiden letzten Methoden bewahren das Seitenverhältnis des Inhalts nicht.

Skalierungswerte kleiner als 1 verringern die von einem Container belegte Fläche. Werte größer als 1 vergrößern sie. Um Inhalt in einem Container zu spiegeln, verwenden Sie einen negativen Skalierungswert. Beispielsweise ergibt ScaleVertical(-1) eine auf den Kopf gestellte Version des ursprünglichen Inhalts.

PdfDocumentBuilder.Create().Generate("positioning-scale.pdf", doc =>
{
    doc.Pages(page =>
    {
        page.Content()
            .MinimalBox()
            .Column(column =>
            {
                var scales = new[] { 0.5f, 0.75f, 1, 1.3f, 1.5f };

                foreach (var scale in scales)
                {
                    var percent = (int)(scale * 100);
                    column.Item()
                        .Scale(scale)
                        .Text(FormattableString.Invariant($"Scale equals {scale} ({percent}%)."))
                            .FontSize(20);

                    column.Item().LineHorizontal(0.5);
                }
            });
    });
});

Das Ergebnis des obigen Codes finden Sie in positioning-scale.pdf.

ScaleToFit

Sie können Inhalt verkleinern, damit er in einen verfügbaren Platz passt. Beispielsweise wenn Sie einen festen Bereich haben, in dem ein Name oder eine Adresse ausgegeben werden soll. Natürlich können Sie die Fläche bei einem längeren Namen vergrößern. Ein einfacherer Ansatz könnte jedoch sein, den Text etwas zu verkleinern. Verwenden Sie die ScaleToFit-Methode, um den Inhalt zu verkleinern.

ScaleToFit bewahrt das Seitenverhältnis des Inhalts. Die Methode vergrößert Inhalt niemals. Beachten Sie, dass diese Methode iterative Berechnungen durchführt. Das kann den PDF-Generierungsprozess verlangsamen.

PdfDocumentBuilder.Create().Generate("positioning-scaletofit.pdf", doc =>
{
    doc.Pages(page =>
    {
        page.Content().Column(column =>
        {
            for (int i = 0; i < 5; i++)
            {
                column.Item()
                    .Width(230 - 20 * i)
                    .Height(20)
                    .ScaleToFit()
                    .Border(b => b.Thickness(0.5))
                    .Text(" This text should fit into the changing width.");
            }
        });
    });
});

Das Ergebnis des obigen Codes finden Sie in positioning-scaletofit.pdf.

AspectRatio

Das Seitenverhältnis definiert die proportionale Beziehung zwischen Breite und Höhe eines Containers. Um das Seitenverhältnis eines Containers zu ermitteln, teilen Sie seine Breite durch seine Höhe.

Verwenden Sie die AspectRatio-Methode, um das Seitenverhältnis für einen Container anzugeben. Das ist hilfreich, wenn Sie einen wiederverwendbaren Container für unterschiedliche Layouts oder Seitengrößen entwerfen.

PdfDocumentBuilder.Create().Generate("positioning-aspectratio.pdf", doc =>
{
    var ratios = new double[] { 0.25, 0.5, 1, 2 };
    foreach (var ratio in ratios)
    {
        var ratioText = ratio.ToString(CultureInfo.InvariantCulture);
        doc.Pages(page =>
        {
            page.Size(200, 200);
            page.Content().Column(column =>
            {
                column.Item()
                    .AspectRatio(ratio)
                    .Background(new PdfGrayColor(75))
                    .Text($"Width / Heigth = {ratioText}");
            });
        });
    }
});

Das Ergebnis des obigen Codes finden Sie in positioning-aspectratio.pdf.

Die Methode hat den optionalen Parameter vom Typ AspectRatioMode. Verwenden Sie diesen Parameter, um anzugeben, wie Inhalt unter Beibehaltung des Seitenverhältnisses skaliert werden soll.

Ein Container mit festgelegtem Seitenverhältnis nimmt so viel Platz wie möglich ein. Je nach Modus versucht der Container, die gesamte verfügbare Fläche (Standard), die Breite oder die Höhe einzunehmen.

Beachten Sie, dass die Bibliothek eine LayoutException auslösen kann. Das geschieht, wenn sie die Anforderungen an Größe, Seitenverhältnis und Seitenverhältnis-Modus nicht erfüllen kann.

Unconstrained

Container können auch völlig ohne Größenbeschränkungen sein. Verwenden Sie die Unconstrained-Methode, um alle Größenbeschränkungen von einem Container zu entfernen.

Inhalt in einem unbeschränkten Container belegt Platz mit einer Größe, die der intrinsischen Größe des Inhalts entspricht. Der unbeschränkte Container selbst belegt keinen Platz. Dadurch können benachbarte Container den Inhalt des unbeschränkten Containers überdecken.

PdfDocumentBuilder.Create().Generate("positioning-unconstrained.pdf", doc =>
{
    doc.Pages(page =>
    {
        page.Content().MinimalBox()
            .Border(b => b.Thickness(0.5))
            .Column(column =>
            {
                column.Item().Text("First item");

                column.Item().Unconstrained()
                    .Text("Second item ignores all size constraints");

                // eine leere Zeile für das dritte Element verwenden
                column.Item().Text(new string(' ', 20))
                    .BackgroundColor(new PdfRgbColor(187, 237, 237), 50);

                column.Item().Text("Fourth item");
            });
    });
});

Das Ergebnis des obigen Codes finden Sie in positioning-unconstrained.pdf. Im Code habe ich für das dritte Element in der Spalte eine Zeile aus Leerzeichen mit halbtransparentem Hintergrund verwendet. Wie Sie sehen, überdeckt das dritte Element das zweite, unbeschränkte Element teilweise.

Position

Die Position eines Containers hängt von einer Reihe von Faktoren ab. Dazu gehören Ausrichtung, Innenabstand, Position des übergeordneten Containers und Inhaltsrichtung. Standardmäßig klebt jeder Container an der ganz linken und obersten verfügbaren Position.

Padding

Eine der häufigsten Anforderungen ist es, etwas Abstand um den Inhalt eines Containers hinzuzufügen. Die LayoutContainer-Klasse stellt eine Reihe von Methoden bereit, um den Innenabstandsbereich eines Containers festzulegen. Der Innenabstandsbereich ist der Raum zwischen Inhalt und Rahmen. Anders gesagt steht Innenabstand für den inneren Raum um den Inhalt.

Die Padding-Methode setzt den Innenabstand auf allen vier Seiten eines Containers auf einmal. Verwenden Sie die PaddingHorizontal-Methode, um den Innenabstand nur für die linke und rechte Seite anzugeben. Die PaddingVertical-Methode tut dasselbe nur für die obere und untere Seite. Um den Innenabstand für eine Seite einzeln festzulegen, verwenden Sie eine der Methoden PaddingTop/Bottom/Left/Right.

Align

Um die Position eines Containers zu ändern, verwenden Sie Ausrichtungsmethoden. Die Methoden AlignLeft/AlignCenter/AlignRight wenden eine horizontale Ausrichtung an und geben einen verschachtelten Container zurück. Die Methoden AlignTop/AlignMiddle/AlignBottom geben einen verschachtelten Container mit entsprechender vertikaler Ausrichtung zurück.

Ein Container mit ausdrücklich angewendeter Ausrichtung nimmt die Fläche mit der minimal erforderlichen Breite und/oder Höhe ein. Der folgende Code erstellt eine Spalte mit zwei Elementen. Ein Element hat eine explizit angewendete Ausrichtung.

PdfDocumentBuilder.Create().Generate("positioning-alignment.pdf", doc =>
{
    var color = new PdfRgbColor(187, 237, 237);
    var text = "Hello";
    doc.Pages(page =>
    {
        page.Size(200, 100);
        page.Content().Column(c =>
        {
            c.Item().Extend().Background(color).Text(text);
            c.Item().Extend().AlignLeft().Background(color).Text(text);
        });
    });
});

Der Aufruf Extend bewirkt, dass beide Elemente die gesamte Seite einnehmen. Ich rufe die Methode AlignLeft für das zweite Element auf. Dieser Aufruf ändert die Position nicht, da der Container des Elements den Text standardmäßig links ausrichtet. Aber die ausdrücklich angewendete Ausrichtung ändert die von dem zweiten Element belegte Fläche.

Das Ergebnis des obigen Codes finden Sie in positioning-alignment.pdf.

Translate

Um einen Container horizontal und/oder vertikal neu zu positionieren, verwenden Sie die Methoden Translate/TranslateX/TranslateY. Die erste verschiebt Container sowohl horizontal als auch vertikal. Die beiden anderen verschieben Container nur in eine Richtung.

Alle diese Methoden überschreiben die Position, bewahren jedoch die Größenbeschränkungen. Der verschobene Container kann andere Container überlappen. Verwenden Sie negative Parameterwerte, um nach links und/oder nach oben zu verschieben. Positive Werte bewirken eine Verschiebung nach rechts und/oder nach unten.

PdfDocumentBuilder.Create().Generate("positioning-translate.pdf", doc =>
{
    doc.Pages(page =>
    {
        page.Size(200, 100);
        page.Content().Row(r =>
        {
            r.ConstantItem(50)
                .Background(new PdfRgbColor(187, 237, 237))
                .Text("Left");

            r.ConstantItem(50)
                // dieses Element 10 Punkte nach links und 5 Punkte nach unten verschieben
                .Translate(-10, 5)
                .Background(new PdfRgbColor(15, 130, 9))
                .Text("Right");
        });
    });
});

Das Ergebnis des obigen Codes finden Sie in positioning-translate.pdf.

Rotate

Gedrehter Inhalt, insbesondere Text, kann Ihre Dokumente auf verschiedene Weise verbessern. Beispielsweise können Sie Platz sparen und Ihr Dokument ansprechender und ästhetischer machen.

Die LayoutContainer-Klasse bietet zwei Ansätze zum Drehen von Inhalt. Unabhängig davon, welchen Ansatz Sie verwenden, berücksichtigt der Container mit dem gedrehten Inhalt Positions- und Größenbeschränkungen.

Drehung um 90 Grad

Die Methoden RotateRight und RotateLeft drehen Inhalt um 90 Grad im bzw. gegen den Uhrzeigersinn.

Der folgende Code zeigt, wie ein Dokument mit vertikalem Text neben dem Hauptinhalt der Seite erstellt wird.

PdfDocumentBuilder.Create().Generate("positioning-rotate.pdf", doc =>
{
    var lightGray = new PdfGrayColor(90);
    doc.Pages(page =>
    {
        page.Size(298, 210);
        page.Content().Row(r =>
        {
            r.AutoItem()
                .RotateLeft()
                .Background(lightGray)
                .Text("This content goes up");

            r.RelativeItem(1)
                .ExtendVertical()
                .PaddingHorizontal(10)
                .Column(t =>
                {
                    for (int i = 0; i < 15; i++)
                        t.Item().Text("The main content line goes here");
                });

            r.AutoItem()
                .RotateRight()
                .Background(lightGray)
                .Text("This content goes down");
        });
    });
});

Das Ergebnis des obigen Codes finden Sie in positioning-rotate.pdf.

Drehung um beliebigen Winkel

Die Rotate-Methode dreht Inhalt um eine beliebige Anzahl von Grad. Positive Werte bewirken eine Drehung im Uhrzeigersinn. Negative Werte stehen für eine Drehung gegen den Uhrzeigersinn.

Der Drehursprung ist die linke obere Ecke des Containers. Der gedrehte Inhalt kann andere Container überlappen.

PdfDocumentBuilder.Create().Generate("positioning-rotate2.pdf", doc =>
{
    doc.Pages(page =>
    {
        page.Size(298, 210);
        page.Content()
            .Padding(25)
            .Background(new PdfGrayColor(70)) // grau
            .AlignCenter()
            .AlignMiddle()

            .Background(new PdfGrayColor(100)) // weiß

            .Rotate(30)

            .Width(100)
            .Height(100)
            .Background(new PdfRgbColor(187, 237, 237)); // blau
    });
});

Das Ergebnis des obigen Codes finden Sie in positioning-rotate2.pdf.

Um den Drehursprung zu ändern, rufen Sie eine der Methoden Translate vor dem Aufruf Rotate auf. Vergessen Sie nicht, den Ursprung nach dem Aufruf wieder zurück zu verschieben.

// den Drehursprung verschieben
.TranslateX(50)
.TranslateY(50)

.Rotate(30)

// zurückverschieben
.TranslateX(-50)
.TranslateY(-50)

Bedingtes Layout

Das Layout Ihres PDF-Dokuments kann von einer Bedingung abhängen. Beispielsweise können Sie für gerade und ungerade Zeilen in einer Spalte unterschiedliche Ausrichtung oder Hintergrundfarbe verwenden.

Verwenden Sie die Container-Methode, um einen verschachtelten Container mit einem von einer Bedingung abhängigen Layout einzufügen. Der Aufruf dieser Methode unterbricht die Aufrufkette nicht.

PdfDocumentBuilder.Create().Generate("positioning-container.pdf", doc =>
{
    doc.Pages(page =>
    {
        page.Content().Column(c =>
        {
            for (int i = 0; i < 15; i++)
            {
                c.Item()
                    .TextStyle(TextStyle.Parent.FontSize(14))
                    .Container(x => i % 2 == 0 ? x.Background(new PdfGrayColor(70)) : x)
                    .Text($"Row {i + 1}");
            }
        });
    });
});

Das Ergebnis des obigen Codes finden Sie in positioning-container.pdf.

DSL

Einige Teile eines Dokuments können dasselbe Layout verwenden. Beispielsweise können sie denselben Rahmenstil haben oder dieselbe Formatierung verwenden. Nach dem Prinzip „don’t repeat yourself“ empfehle ich, gemeinsamen Code in eine Methode auszulagern.

Die Verwendung einer Erweiterungsmethode für den gemeinsamen Code bietet zwei Vorteile:

  • Sie können die Methode in Methodenaufrufketten verwenden
  • Sie können einer Gruppe von Methodenaufrufen einen aussagekräftigen Namen geben

Mit diesen Vorteilen können Sie eine domänenspezifische Sprache (DSL) erstellen. Mit der DSL kann Ihr Layout-Code kürzer und leichter verständlich sein.

static class LayoutHelpers
{
    public static LayoutContainer NumberCell(this Table table)
        => table.Cell().Border(b => b.Thickness(0.5)).PaddingHorizontal(10);
}

PdfDocumentBuilder.Create().Generate("positioning-dsl.pdf", doc => doc.Pages(page =>
{
    page.Content().Table(t =>
    {
        t.Columns(c =>
        {
            for (int i = 0; i < 4; ++i)
                c.ConstantColumn(50);
        });

        for (int i = 0; i < 16; i++)
            t.NumberCell().Text($"{i + 1}");
    });
}));

Rendering-Prozess

Das Layout-Add-on ordnet jeden Inhalt, den Sie in einen Container einfügen, gemäß Größen- und Positionsbeschränkungen an. Manche Inhalte können sich über mehrere Seiten erstrecken. Es gibt eine feste Reihenfolge, in der Inhalt gerendert wird. Inhaltsfluss ist eine andere Bezeichnung für diese Reihenfolge.

Die LayoutContainer-Klasse bietet einige Methoden zum Feinjustieren des Inhaltsflusses. Sie benötigen sie vielleicht nicht immer, aber es gibt Fälle, in denen sich das gewünschte Layout auf keine andere Weise erreichen lässt.

PageBreak

Wenn Sie einen Inhaltsblock auf einer neuen Seite beginnen müssen, verwenden Sie die PageBreak-Methode. Sie können die Methode beispielsweise verwenden, um ein Column-Element auf einer neuen Seite zu beginnen.

Hier ist ein Beispielcode, der eine Spalte so aufteilt, dass jede Seite nur zwei Zeilen enthält.

PdfDocumentBuilder.Create().Generate("positioning-pagebreak.pdf", doc => doc.Pages(page =>
{
    page.Size(200, 100);
    page.Content().Column(c =>
    {
        for (int i = 1; i <= 10; ++i)
        {
            c.Item().Text($"Item {i}");

            if (i % 2 == 0)
                c.Item().PageBreak();
        }
    });
}));

Das Ergebnis des obigen Codes finden Sie in positioning-pagebreak.pdf.

ShowIf

Abhängig von einer Bedingung müssen Sie möglicherweise einen Container ein- oder ausblenden. Es gibt die Methode ShowIf, die für diesen Sonderfall des bedingten Layouts im Wesentlichen syntaktischer Zucker ist.

Im folgenden Code verwende ich die Methode ShowIf, um nach jeweils 5 Elementen in einer Reihe eine vertikale Linie einzufügen.

PdfDocumentBuilder.Create().Generate("positioning-showif.pdf", doc => doc.Pages(page =>
{
    page.Size(200, 100);
    page.Content().Row(r =>
    {
        for (int i = 0; i < 10; ++i)
        {
            r.AutoItem().Text(i.ToString());
            r.AutoItem().ShowIf(i > 0 && (i + 1) % 5 == 0).LineVertical(0.5);
        }
    });
}));

Das Ergebnis des obigen Codes finden Sie in positioning-showif.pdf.

ShowOnce

Sie können verhindern, dass sich ein Inhalt auf den nächsten Seiten wiederholt. Verwenden Sie die ShowOnce-Methode, um der Layout-Engine mitzuteilen, den Inhalt nur einmal vollständig zu rendern.

Sehen Sie sich den folgenden Code an, um zu sehen, wie der Aufruf ShowOnce verhindert, dass „Environment“ auf der zweiten Seite erscheint.

PdfDocumentBuilder.Create().Generate("positioning-showonce.pdf", doc => doc.Pages(page =>
{
    page.Size(200, 100);
    page.Content().Row(r =>
    {
        r.RelativeItem()
            .Background(new PdfGrayColor(75))
            .Border(b => b.Thickness(0.5))
            .Padding(5)
            .ShowOnce()
            .Text("Environment");

        r.RelativeItem()
            .Border(b => b.Thickness(0.5))
            .Padding(5)
            .Column(c =>
            {
                c.Item().Text(Environment.OSVersion.VersionString);
                c.Item().Text(string.Empty);
                c.Item().Text(
                    Environment.GetEnvironmentVariable("PROCESSOR_IDENTIFIER")
                    ?? string.Empty
                );
            });
    });
}));

Das Ergebnis des obigen Codes finden Sie in positioning-showonce.pdf.

ShowEntire

Das Standardverhalten besteht darin, Inhalt zwischen Seiten aufzuteilen, wenn er nicht auf eine Seite passt. Verwenden Sie die ShowEntire-Methode, um den gesamten Container auf einer Seite zu rendern.

Beachten Sie, dass die Bibliothek eine LayoutException auslöst, wenn es nicht möglich ist, den gesamten Inhalt auf einer Seite unterzubringen.

Aufgrund des Aufrufs ShowEntire im folgenden Code beginnt der Text des zweiten Elements erst auf der zweiten Seite. Ohne den Aufruf würde er auf der ersten Seite unmittelbar nach dem Text des ersten Elements beginnen.

PdfDocumentBuilder.Create().Generate("positioning-showentire.pdf", doc => doc.Pages(page =>
{
    page.Size(100, 100);
    page.Content().Column(c =>
    {
        c.Item().Text(t =>
        {
            for (var i = 0; i < 4; i++)
                t.Line($"First item line {i + 1}");
        });

        c.Item()
            .Background(new PdfRgbColor(250, 123, 5))
            .ShowEntire()
            .Text(t =>
            {
                for (var i = 0; i < 4; i++)
                    t.Line($"Second item line {i + 1}");
            });
    });
}));

Das Ergebnis des obigen Codes finden Sie in positioning-showentire.pdf.

EnsureSpace

In gewissem Sinne ist EnsureSpace ein Sonderfall der Methode ShowEntire. Der Unterschied besteht darin, dass EnsureSpace nicht verlangt, dass der gesamte Inhalt auf eine Seite passt. Die Methode versucht nur, einen Teil des Inhalts mit der angegebenen Höhe unterzubringen. Alles andere wird auf die nächste Seite verschoben.

Wenn der freie Bereich der aktuellen Seite eine geringere Höhe als die angeforderte hat, wird der gesamte Inhalt auf einer neuen Seite gerendert. In diesem Fall erzeugt die Methode dasselbe Ergebnis wie die Methode ShowEntire.

StopPaging

Verwenden Sie die StopPaging-Methode, um die Ausgabe auf höchstens einer Seite zu erzeugen. Der Aufruf dieser Methode für einen Container verhindert dessen Seiteneinteilung. Das Layout-Add-on teilt den Inhalt dieses Containers nicht über Seiten auf. Es rendert keine Daten, die nicht auf eine Seite passen.

Der folgende Beispielcode fügt dem Dokument zwei Seitenmengen hinzu. Beide Mengen verwenden eine Liste von Wochentagnamen als Inhalt. Die erste Menge hat nur eine Seite, weil der Code die Methode StopPaging für den Inhaltscontainer der Seiten aufruft.

PdfDocumentBuilder.Create().Generate("positioning-stoppaging.pdf", doc =>
{
    static Action<TextContainer> produceText(string heading)
    {
        var text = string.Join('\n', DateTimeFormatInfo.InvariantInfo.DayNames);
        return t =>
        {
            t.Line(heading).BackgroundColor(new PdfRgbColor(250, 123, 5));
            t.Span(text);
        };
    }

    doc.Pages(page =>
    {
        page.Size(100, 100);
        page.Content()
            .StopPaging()
            .Text(produceText("Without paging:"));
    });

    doc.Pages(page =>
    {
        page.Size(100, 100);
        page.Content()
            .Text(produceText("Default behaviour:"));
    });
});

Das Ergebnis des obigen Codes finden Sie in positioning-stoppaging.pdf.

SkipOnce

Sie können das Erscheinen von Inhalt verzögern. Wenn ein Container auf mehr als einer Seite erscheint, verwenden Sie SkipOnce, um die erste Seite zu überspringen und den Inhalt auf allen Seiten ab der zweiten Seite zu rendern.

Diese Fähigkeit ist für alle Arten von Kopfzeilen nützlich, Sie können sie aber auch für andere Inhalte verwenden. Sehen Sie sich den folgenden Code an, um zu sehen, wie der Aufruf SkipOnce verhindert, dass die Kopfzeile auf der ersten Seite erscheint.

PdfDocumentBuilder.Create().Generate("positioning-skiponce.pdf", doc => doc.Pages(page =>
{
    page.Size(298, 210);

    page.Header()
        .SkipOnce()
        .Text("This header will appear starting from page 2")
        .Style(TextStyle.Parent.Underline());

    page.Content().Column(c =>
    {
        for (int i = 0; i < 5; i++)
        {
            if (i > 0)
                c.Item().PageBreak();

            c.Item().Text($"Page {i + 1}");
        }
    });
}));

Das Ergebnis des obigen Codes finden Sie in positioning-skiponce.pdf.

Inhaltsrichtung

Die standardmäßige Inhaltsrichtung ist von links nach rechts. Container richten ihren Text und anderen Inhalt links aus.

Es gibt jedoch Sprachen, die von rechts nach links geschrieben werden, z. B. Arabisch und Hebräisch. Wenn Sie Inhalt in diesen Sprachen erstellen, verwenden Sie die ContentFromRightToLeft-Methode. Ein Aufruf davon ändert die Inhaltsrichtung des Containers auf von rechts nach links. Die Methode ändert auch die Standardausrichtung.

Wenn der Großteil des Inhalts auf Ihren Seiten in einer RTL-Sprache ist, können Sie von rechts nach links als standardmäßige Inhaltsrichtung für die Seiten festlegen. Verwenden Sie dafür die Methode PageLayout.ContentFromRightToLeft. Um dann die standardmäßige Inhaltsrichtung für ausgewählte Container zu überschreiben, verwenden Sie die Methode ContentFromLeftToRight.

Beachten Sie, dass die Inhaltsrichtung die ausdrücklich angegebene Ausrichtung nicht beeinflusst. Beispielsweise bleibt rechts ausgerichteter Inhalt auf der rechten Seite, unabhängig davon, welche Inhaltsrichtung Sie für seinen Container festlegen. Die visuelle Reihenfolge der untergeordneten Elemente ist je nach Inhaltsrichtung unterschiedlich.