Seiten mit BpPage
Mit BpPage definieren Sie Listen, Detailansichten und Dashboards in C#.
Studio und Portal stellen die zurückgegebenen UI-Bausteine dar.
Seite definieren
Eine Seite erbt von BpPage und liefert in BuildAsync eine Liste von Bausteinen:
public sealed class UebersichtSeite(IBpSession session) : BpPage
{
public override string Title => "Übersicht";
public override Task<Page> BuildAsync(PageRequest request, CancellationToken cancellationToken)
{
return Task.FromResult(new Page(
[
new Header("Adressen") { Subtitle = "Stand von heute" },
new Note("Hier steht später eine Tabelle.")
]));
}
}
Diese Properties steuern Titel, Zielgruppe und Navigation:
| Override | Bedeutung |
|---|---|
Title |
Titel in Menü und Brotkrumen |
Audience |
Portal für Endanwender unter /apps (Voreinstellung), Admin für einen Reiter auf der Modulseite in Studio |
ShowInMenu |
false nimmt die Seite aus dem Menü, erreichbar bleibt sie über Links |
Order |
Sortierung im Menü |
Bei Interaktionen wird BuildAsync erneut aufgerufen. Halten Sie Seiten zustandslos und
lesend; begrenzen Sie Abfragen mit includes: und einem Seitenlimit.
Beispiel: Adressbuch mit Suche
Das Adressbuch zeigt 20 Adressen pro Seite und verlinkt auf die nachfolgende Detailseite:
public sealed class AdressbuchSeite(IBpSession session) : BpPage
{
public override string Title => "Adressbuch";
public override Task<Page> BuildAsync(
PageRequest request,
CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
const int pageSize = 20;
var search = request.Text("search");
var page = Math.Clamp(request.Int("page", 1), 1, 10000);
var query = session.QueryDataSet<Adressen>(includes: ["AdrNr", "SuchBeg"]);
if (!string.IsNullOrWhiteSpace(search))
query = query.Where(adresse => adresse.SuchBeg!.Contains(search));
var rows = query
.OrderBy(adresse => adresse.AdrNr)
.Skip((page - 1) * pageSize)
.Take(pageSize + 1)
.ToList();
return Task.FromResult(new Page(
[
new Header("Adressbuch"),
new SearchBox("search") { Placeholder = "Suchbegriff" },
new Table
{
Columns = [new TableColumn("Nr.", Mono: true), new TableColumn("Name")],
Rows = rows.Take(pageSize).Select(adresse => new TableRow(
[adresse.AdrNr ?? "", adresse.SuchBeg ?? ""])
{
Opens = Link.To<AdresseSeite>(("id", adresse.AdrNr!))
}).ToList()
},
new Pager("page") { HasMore = rows.Count > pageSize }
]));
}
}
Suchwert und Seitenzahl stehen unter den Baustein-IDs im PageRequest bereit:
| Zugriff | Verhalten |
|---|---|
request.Text("search") |
Suchwert oder null, wenn er fehlt oder leer ist |
request.Int("page", 1) |
Seitenzahl oder der Rückfallwert |
request.Required("id") |
Pflichtwert; fehlt er, wird eine fehlerhafte Anfrage gemeldet |
Pager.HasMore aktiviert die nächste Seite. Eine geänderte Suche setzt den Pager zurück.
Seiten miteinander verknüpfen
Link.To<T> öffnet eine Seite mit den angegebenen Parametern:
new TableRow([adr.AdrNr!, adr.SuchBeg ?? string.Empty])
{
Opens = Link.To<AdresseSeite>(("id", adr.AdrNr!))
}
Ein Klick auf die Zeile öffnet AdresseSeite, und dort steht das Argument im PageRequest
bereit:
public sealed class AdresseSeite(IBpSession session) : BpPage
{
public override string Title => "Adresse";
// Detailseite: über Links erreichbar, aber nicht im Menü.
public override bool ShowInMenu => false;
public override Task<Page> BuildAsync(PageRequest request, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
var adrNr = request.Required("id");
var adresse = session
.QueryDataSet<Adressen>(includes: ["AdrNr", "SuchBeg", "Status", "Branche"])
.FirstOrDefault(adr => adr.AdrNr == adrNr)
?? throw new PageArgumentException($"Keine Adresse mit Nummer '{adrNr}' gefunden.");
return Task.FromResult(new Page(
[
new Header(adresse.SuchBeg ?? adrNr)
{
Subtitle = adrNr,
Chips = [new KeyValueRow("Status", adresse.Status ?? "-")]
}
]));
}
}
Mit PageArgumentException melden Sie einen ungültigen Parameter als fehlerhafte Anfrage.
Seiten aufrufen
Nach dem erneuten Laden des Moduls ist Adressbuch im Menü der freigeschalteten App erreichbar.