19. Jul 2021
Lesedauer 13 Min.
Mit .NET ins Web
Web-Apps mit Blazor, Teil 4
Das UI moderner Webapplikationen rein mit HTML und CSS zu gestalten widerspricht dem Komponentenansatz von Blazor. Drittanbieter wie Syncfusion oder Telerik bieten Abhilfe.

Auf dem Lernpfad der modernen Webapplikation mit Blazor sind wir schon ein Stück fortgeschritten und haben Ansatz und technische Hintergründe, Grundlagen der Blazor-Komponenten und die Arbeit mit Formularen betrachtet [1] [2] [3]. Eine Webapplikation muss die Anwender aber auch mit einer modernen, ansprechenden und benutzerfreundlichen Oberfläche überzeugen.Grundsätzlich haben Sie dafür alles an Bord – HTML und CSS sind die Basis. An dieser Stelle könnten Sie bereits aufhören, denn jedes Element des User Interface können Sie mit den beiden Technologien zusammenbauen. Das ist jedoch nicht der Sinn von Blazor. Microsoft möchte mit diesem Framework den Entwicklungsprozess beschleunigen, daher gilt der Komponentenansatz auch für das User Interface.
Material Design und Fluent Design
Das Material Design [16] basiert auf dem Einsatz von kartenähnlichen Flächen und dem Flat Design (Minimalismus). Zusätzlich verwendet dieser Designentwurf Animationen und Schatten, um einen leichten Tiefeneffekt zu erzeugen. Damit wird gezeigt, welche Bereiche wichtige Informationen enthalten beziehungsweise interaktiv sind.
.NET-Entwickler haben eine lange Historie mit Komponentenbibliotheken (WinForms, WPF, Win UI, Xamarin). Und dieses Prinzip gilt auch für Webapplikationen auf der Basis von Blazor. Da das Blazor-Framework hier zunächst keine umfassenden User-Interface-Komponenten bereitstellt, ist dies eine Spielwiese von Third-Party-Anbietern.
Komponentenbibliotheken
Im Lauf des Artikels werden wir die Arbeit mit der einen oder anderen Bibliothek erläutern. Typische Fragen lauten:- Wie werden die Bibliotheken üblicherweise in ein aktuelles Projekt eingebunden?
- An welchen Dateien müssen wir Verweise ergänzen?
- Wie nutzen wir in einer eigenen Blazor-Komponente die vordefinierten User-Interface-Bausteine?
Listing 1: Login-Formular mit Radzen-Komponente
<span class="hljs-keyword">@page</span> <span class="hljs-string">"/radzenTest"</span> <br/>&lt;h3&gt;RadzenTest&lt;/h3&gt; <br/><br/>&lt;div class=<span class="hljs-string">"my-5"</span>&gt; <br/> &lt;RadzenCard&gt; <br/> &lt;RadzenLogin AllowRegister=<span class="hljs-string">"true"</span> <br/> AllowResetPassword=<span class="hljs-string">"true"</span> <br/> LoginText=<span class="hljs-string">"Einloggen"</span> UserText=<span class="hljs-string">"Benutzername"</span> <br/> PasswordText=<span class="hljs-string">"Passwort"</span> <br/> UserRequired=<span class="hljs-string">"Benutzername erforderlich"</span> <br/> PasswordRequired=<span class="hljs-string">"Passwort erforderlich"</span> <br/> RegisterText=<span class="hljs-string">"Registrieren"</span> <br/> RegisterMessageText=<span class="hljs-string">"Sie haben noch keinen </span><br/><span class="hljs-string"> Account?"</span> <br/> ResetPasswordText=<span class="hljs-string">"Passwort zurücksetzen"</span> <br/> Style=<span class="hljs-string">"margin-bottom: 20px;"</span> /&gt; <br/> &lt;/RadzenCard&gt; <br/>&lt;/div&gt; <br/><br/><span class="hljs-variable">@code</span> { <br/>}
Radzen Blazor Components [4]: Es handelt sich um einen Satz von mehr als 60 nativen Blazor-UI-Steuerelementen. Die Komponenten können sowohl für Blazor-Server- als auch für Blazor-WebAssembly-Apps eingesetzt werden. Die Bibliothek ist Open Source und steht auch für einen kommerziellen Einsatz zur Verfügung. Die Palette der UI-Komponenten deckt einen Großteil der üblichen Anforderungen moderner Webapplikationen ab. Enthalten sind Basiskomponenten wie Button, Image, Menu und ProgressBar, aber auch leistungsfähige DataGridControls, HTML-Editoren, Chart-Elemente, Elemente zur Formulargestaltung und vieles mehr.In der Dokumentation auf der Webseite findet man die Hinweise für die Installation beziehungsweise die Verwendung im eigenen Projekt. Die Dokumentation zu den einzelnen Komponenten beinhaltet eine Live-Vorschau. Mit deren Hilfe lässt sich direkt die Eignung der Komponente für das eigene Projekt beurteilen. Am Beispiel einer Chart-Komponente sind in Bild 1 Ansicht und Quellcode dargestellt. Der Hersteller bietet darüber hinaus ein visuelles Design-Tool (kommerziell) zur Gestaltung des User Interface für datengebundene Business-Webapplikationen auf der Basis von Blazor und Angular. Dabei wird gemäß den Angaben auf der Webseite der gesamte Lebenszyklus einer Webapplikation, vom Entwurf der Benutzeroberfläche bis hin zum Deployment, unterstützt. Damit haben wir es mit einem RAD-Tool für das Web Development zu tun. Uns interessieren hier jedoch die Blazor-Komponenten für den Einsatz in eigenen Projekten.

Chart-Komponentevon Radzen (linksdie Preview, rechts der Sourcecode)(Bild 1)
Autor
Der bekannte Hersteller Syncfusion [5] bietet auch für Webapplikationen auf der Basis von Blazor ein umfassendes Set von Komponenten für die Gestaltung des User Interface. Auch hier ist eine Nutzung der Komponenten in beiden Blazor-App-Typen (Server und WebAssembly) möglich. Neben kostenpflichtigen Lizenzen steht auch die Community-Lizenz zur Verfügung, die eine eingeschränkte kommerzielle Nutzung erlaubt. Damit ist dieses Set an Komponenten ideal für den Einstieg in die Welt der Blazor-Apps. Die Palette der angebotenen User-Interface-Komponenten deckt auch hier das gesamte Spektrum ab und ist mit über 70 Komponenten ebenfalls sehr umfangreich (Bild 2). Darunter finden sich auch sehr funktionsreiche Komponenten, wie zum Beispiel ein komplettes Kanban-Board (Bild 3). Hier wird schnell klar, welchen Vorteil der Einsatz von fertigen Komponenten für das User Interface bietet.

Komponentenpalettevon Syncfusion(Bild 2)
Autor

Kanban-Komponentevon Syncfusion(Bild 3)
Autor
Neben der Einbindung der Bibliotheken in das eigene Blazor-Projekt, etwa über NuGet, ist auch der individuelle Lizenz-Key zu hinterlegen. Die Dokumentation gibt dazu entsprechende Auskunft.Auch die Komponentenanbieter DevExpress [6] und Telerik [7] unterstützen mit ihren UI-Komponenten inzwischen das Web-Framework Blazor. Beide Anbieter stellen jeweils ein umfassendes Set an Komponenten (Telerik mehr als 75; DevExpress über 35) zur Verfügung. Ein Test kann auf der Basis von Trial-Versionen durchgeführt werden.Erwähnen möchten wir ebenso MatBlazor [8]. Es handelt sich um kein kommerzielles Projekt. Die Komponenten werden kostenfrei zur Verfügung gestellt. MatBlazor basiert auf Material Design. Die Komponentenpalette ist auch hier umfangreich und umfasst primär Elemente für klassische datengetriebene Oberflächen (Buttons, Dialoge, DataTable et cetera). Das Design ist schlicht und lässt sich über Themen im Kontext von Material Design anpassen.Bei BlazorStrap [9] handelt es sich um ein UI-Framework für Blazor, welches sich auf Bootstrap konzentriert. Es werden die typischen UI-Komponenten mit Bootstrap-Design bereitgestellt. Die Bibliothek kann kostenfrei genutzt werden. Ebenfalls auf Material Design basiert MudBlazor [10]. Es werden Komponenten für Blazor Server und Blazor WebAssembly angeboten. Die Bibliothek steht quelloffen auf GitHub zur Verfügung. Die Palette an Komponenten umfasst ebenso die üblichen Controls. BlazorFluentUI [11] setzt entgegen vielen anderen Bibliotheken auf den Fluent-Design-Ansatz.Keine Komponentenbibliothek im eigentlichen Sinne ist Blazor Extensions[12]. Dennoch lohnt sich ein Blick auf diese Erweiterungen. Für die Gestaltung des User Interface findet sich dort die Blazor-Extension Canvas, welche einen Wrapper für das HTML5-Canvas-Element bietet. Diese Erweiterung steht für die beiden Anwendungstypen Blazor-Server-Apps und Blazor-WebAssembly-Apps zur Verfügung. Man nutzt sie für Webapplikationen mit 2D- oder 3D-Grafiken. Der Wrapper für Blazor unterstützt sowohl Canvas 2D als auch WebGL (3D).Diese Liste der Bibliotheken ist nicht vollständig, sie sollte jedoch bereits einen guten Überblick über die vielfältigen Optionen zur Gestaltung der Benutzeroberfläche mit Komponenten für Blazor-Apps bieten. Kommen wir nun zur praktischen Umsetzung anhand einiger Beispiele.
Ein User Interface mit Radzen
Wir werden uns nun konkret die Arbeit mit vordefinierten UI-Komponenten ansehen. Dazu wollen wir in einem ersten Schritt die Komponenten von Radzen verwenden. Sie benötigen dafür eine Test-Applikation. Erstellen Sie diese über den Assistenten von Visual Studio oder verwenden Sie unsere Vorlage. Fügen Sie eine neue Seite hinzu, um dann testweise Inhalte für das User Interface zu erstellen. Wir haben diese Seite RadzenTest.razor genannt. Kommen wir nun dazu, wie man die Komponenten aus der Radzen-Bibliothek nutzt. Dazu sind die folgenden Schritte notwendig:- Package hinzufügen: Hinzufügen des Pakets Radzen.Blazor über NuGet in das Projekt. Das kann über die Kommandozeile mit dotnet add package Radzen.Blazor oder aber komfortabel über den Package-Manager von Visual Studio erfolgen.
- Importieren der Namensräume: Fügen Sie die beiden using-Anweisungen@using Radzen und @using Radzen.Blazor der Datei _Imports.razor aus dem Root-Verzeichnis der Applikation hinzu.
- Thema hinzufügen: Hier müssen wir unterscheiden, ob wir eine serverseitige oder eine clientseitige Blazor-App erstellen. Bei einer serverseitigen App editieren wir die Datei _Host.cshtml; bei einer clientseitigen App ergänzen wir die Datei wwwroot/index.html um die folgende CSS-Datei: <link rel=“stylesheet“ href=“_content/Radzen.Blazor/css/default-base.css“>. Damit stellen wir sicher, dass die Bibliothek das richtige Styling und Design verwendet.
- Einbindung des JavaScript-Verweises: Auch hier unterscheiden wir zwischen serverseitiger oder clientseitiger Blazor-App. Das heißt, dass wir entweder erneut die Datei _Host.cshtml oder aber die Datei wwwroot/index.html jeweils um den folgenden Eintrag ergänzen: <script src=“_content/Radzen.Blazor/Radzen.Blazor.js“></script>

Reiche Auswahlan Komponenten in der Bibliothek Radzen(Bild 4)
Bild: Radzen.com [4]
<div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"my-5"</span>>
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">RadzenCard</span>></span> </span>
<span class="xml"> <span class="hljs-tag"><<span class="hljs-name">RadzenLogin</span> <span class="hljs-attr">AllowRegister</span>=</span></span>
<span class="xml"><span class="hljs-tag"> <span class="hljs-string">"false"</span> </span></span>
<span class="xml"><span class="hljs-tag"> <span class="hljs-attr">AllowResetPassword</span>=<span class="hljs-string">"false"</span> </span></span>
<span class="xml"><span class="hljs-tag"> <span class="hljs-attr">Style</span>=<span class="hljs-string">"margin-bottom: </span></span></span>
<span class="xml"><span class="hljs-tag"><span class="hljs-string"> 20px;"</span> /></span> </span>
<span class="xml"> <span class="hljs-tag"></<span class="hljs-name">RadzenCard</span>></span> </span>
<span class="xml"><span class="hljs-tag"></<span class="hljs-name">div</span>></span></span>
Das umschließende <div\>-Element dient als Container, damit wir das Login-Formular entsprechend im Layout ausrichten können. Wenn Sie die App starten, bekommen Sie bereits ein Standard-Login-Formular. Dieses lässt sich über die Properties der Komponente nach unseren Wünschen anpassen. Die Dokumentation gibt Auskunft, welche Optionen wir haben. Das Login-Formular von Radzen macht die Properties und Events gemäß Bild 5 nach außen verfügbar [13].

Properties und Eventsdes Login-Formulars von Radzen(Bild 5)
Bild: Radzen.com [13]
Mit diesen Informationen können wir unser Login-Formular nunmehr wunschgemäß anpassen, zum Beispiel hinsichtlich der angezeigten Texte. Listing 1 zeigt den Quellcode unserer Komponente. Das Ergebnis ist in Bild 6 dargestellt.
Listing 1: Login-Formular mit Radzen-Komponente
<span class="hljs-keyword">@page</span> <span class="hljs-string">"/radzenTest"</span> <br/>&lt;h3&gt;RadzenTest&lt;/h3&gt; <br/><br/>&lt;div class=<span class="hljs-string">"my-5"</span>&gt; <br/> &lt;RadzenCard&gt; <br/> &lt;RadzenLogin AllowRegister=<span class="hljs-string">"true"</span> <br/> AllowResetPassword=<span class="hljs-string">"true"</span> <br/> LoginText=<span class="hljs-string">"Einloggen"</span> UserText=<span class="hljs-string">"Benutzername"</span> <br/> PasswordText=<span class="hljs-string">"Passwort"</span> <br/> UserRequired=<span class="hljs-string">"Benutzername erforderlich"</span> <br/> PasswordRequired=<span class="hljs-string">"Passwort erforderlich"</span> <br/> RegisterText=<span class="hljs-string">"Registrieren"</span> <br/> RegisterMessageText=<span class="hljs-string">"Sie haben noch keinen </span><br/><span class="hljs-string"> Account?"</span> <br/> ResetPasswordText=<span class="hljs-string">"Passwort zurücksetzen"</span> <br/> Style=<span class="hljs-string">"margin-bottom: 20px;"</span> /&gt; <br/> &lt;/RadzenCard&gt; <br/>&lt;/div&gt; <br/><br/><span class="hljs-variable">@code</span> { <br/>}

Das angepasste Login-Formularmit Radzen(Bild 6)
Autor
Als zweites Beispiel sehen wir uns noch den Einbau eines Menüs an. Dieses wird insbesondere in Applikationen benötigt, die eine dokumentenbasierte Interaktion (Datei öffnen, Element hinzufügen, Daten exportieren et cetera) umsetzen. Ein solches Anwendungsmenü gab es nicht nur in früheren Desktop-Applikationen, sondern man kann es auch in Webapplikationen sinnvoll verwenden. Das Vorhaben gelingt leichtgewichtig mithilfe der Komponente Radzen Blazor Menu. Ein Menü besteht hier aus einzelnen MenuItems, welche auch geschachtelt (Untermenüs) werden können. Die Eigenschaften des gesamten Menüs (Menu) und der einzelnen Einträge (MenuItems) zeigt Bild 7. Die Verwendung der Komponente ist dann denkbar einfach und erinnert in großen Teilen an den Aufbau von Menüs mittels XAML-Dialekt in Windows-Applikationen (WPF, UWP, Win UI). Listing 2 zeigt das Vorgehen. Für die MenuItem-Elemente definieren wir die Text- und die Icon-Eigenschaft. Für die Icons greifen wir auf die Material-Icons von Google zurück, die bereits im Projekt verfügbar sind. Unter [14] können Sie das passende Icon und den zugehörigen Namen auswählen (Bild 8).

Eigenschaftender Radzen-Komponenten Menu und MenuItem(Bild 7)
Autor

Auswahl eines passenden Iconsaus dem Material Design(Bild 8)
Autor
Listing 2: Ein Menü mittels Radzen-Komponente
<span class="hljs-tag">&lt;<span class="hljs-name">RadzenMenu</span>&gt;</span> <br/> <span class="hljs-tag">&lt;<span class="hljs-name">RadzenMenuItem</span> <span class="hljs-attr">Text</span>=<span class="hljs-string">"File"</span>&gt;</span> <br/> <span class="hljs-tag">&lt;<span class="hljs-name">RadzenMenuItem</span> <span class="hljs-attr">Text</span>=<span class="hljs-string">"Neu"</span> <span class="hljs-attr">Icon</span>=<span class="hljs-string">"add"</span>&gt;</span><br/> <span class="hljs-tag">&lt;/<span class="hljs-name">RadzenMenuItem</span>&gt;</span> <br/> <span class="hljs-tag">&lt;<span class="hljs-name">RadzenMenuItem</span> <span class="hljs-attr">Text</span>=<span class="hljs-string">"Öffnen"</span> </span><br/><span class="hljs-tag"> <span class="hljs-attr">Icon</span>=<span class="hljs-string">"open_in_new"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">RadzenMenuItem</span>&gt;</span> <br/> <span class="hljs-tag">&lt;<span class="hljs-name">RadzenMenuItem</span> <span class="hljs-attr">Text</span>=<span class="hljs-string">"Speichern"</span> <span class="hljs-attr">Icon</span>=<span class="hljs-string">"save"</span>&gt;</span><br/> <span class="hljs-tag">&lt;/<span class="hljs-name">RadzenMenuItem</span>&gt;</span> <br/> <span class="hljs-tag">&lt;/<span class="hljs-name">RadzenMenuItem</span>&gt;</span> <br/> <span class="hljs-tag">&lt;<span class="hljs-name">RadzenMenuItem</span> <span class="hljs-attr">Text</span>=<span class="hljs-string">"Bearbeiten"</span>&gt;</span> <br/> <span class="hljs-tag">&lt;<span class="hljs-name">RadzenMenuItem</span> <span class="hljs-attr">Text</span>=<span class="hljs-string">"Kopieren"</span> </span><br/><span class="hljs-tag"> <span class="hljs-attr">Icon</span>=<span class="hljs-string">"content_copy"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">RadzenMenuItem</span>&gt;</span> <br/> <span class="hljs-tag">&lt;<span class="hljs-name">RadzenMenuItem</span> <span class="hljs-attr">Text</span>=<span class="hljs-string">"Ausschneiden"</span> </span><br/><span class="hljs-tag"> <span class="hljs-attr">Icon</span>=<span class="hljs-string">"content_cut"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">RadzenMenuItem</span>&gt;</span> <br/> <span class="hljs-tag">&lt;<span class="hljs-name">RadzenMenuItem</span> <span class="hljs-attr">Text</span>=<span class="hljs-string">"Einfügen"</span> </span><br/><span class="hljs-tag"> <span class="hljs-attr">Icon</span>=<span class="hljs-string">"content_paste"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">RadzenMenuItem</span>&gt;</span> <br/> <span class="hljs-tag">&lt;/<span class="hljs-name">RadzenMenuItem</span>&gt;</span> <br/><span class="hljs-tag">&lt;/<span class="hljs-name">RadzenMenu</span>&gt;</span>
Es stellt sich nun noch die Frage, wie man auf einen Mausklick auf ein MenuItem-Element reagiert. Die Komponente besitzt keinen eigenen Click-Event. Hinweis: Verwechseln Sie nicht die JavaScript-Events mit den Events der Razor-Komponenten (Bild 9). Ein JavaScript-@onclick-Event gibt es, dieses nutzen wir jedoch nicht, denn wir wollen die Programmlogik mit C# und der Razor-Syntax umsetzen und nicht mit JavaScript. Vielmehr nutzen wir den Click-Event der <Menu/>-Komponente und ordnen diesem Event einen Ereignishandler zu. Innerhalb der Methode zur Behandlung des Ereignisses können wir dann über eine einfache if-Abfrage herausbekommen, welcher Menüpunkt vom Nutzer angeklickt wurde. Sie finden den zugehörigen Quellcode in Listing 3.

JavaScript-Eventssind hier nicht passend(Bild 9)
Autor
Listing 3: Ein Menü mittels Radzen-Komponente und Ereignisbehandlung
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">RadzenMenu</span> <span class="hljs-attr">Click</span>=<span class="hljs-string">"MenuClick"</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">RadzenMenuItem</span> <span class="hljs-attr">Text</span>=<span class="hljs-string">"File"</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">RadzenMenuItem</span> <span class="hljs-attr">Text</span>=<span class="hljs-string">"Neu"</span> <span class="hljs-attr">Icon</span>=<span class="hljs-string">"add"</span>&gt;</span></span><br/><span class="xml"> <span class="hljs-tag">&lt;/<span class="hljs-name">RadzenMenuItem</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">RadzenMenuItem</span> <span class="hljs-attr">Text</span>=<span class="hljs-string">"Öffnen"</span> </span></span><br/><span class="xml"><span class="hljs-tag"> <span class="hljs-attr">Icon</span>=<span class="hljs-string">"open_in_new"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">RadzenMenuItem</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">RadzenMenuItem</span> <span class="hljs-attr">Text</span>=<span class="hljs-string">"Speichern"</span> <span class="hljs-attr">Icon</span>=<span class="hljs-string">"save"</span>&gt;</span></span><br/><span class="xml"> <span class="hljs-tag">&lt;/<span class="hljs-name">RadzenMenuItem</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;/<span class="hljs-name">RadzenMenuItem</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">RadzenMenuItem</span> <span class="hljs-attr">Text</span>=<span class="hljs-string">"Bearbeiten"</span>&gt;</span> </span><br/><span class="xml"> ... </span><br/><span class="xml"> <span class="hljs-tag">&lt;/<span class="hljs-name">RadzenMenuItem</span>&gt;</span> </span><br/><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">RadzenMenu</span>&gt;</span> </span><br/><br/><span class="xml">@code </span><span class="hljs-template-variable">{ </span><br/><span class="hljs-template-variable"> void MenuClick(MenuItemEventArgs e) </span><br/><span class="hljs-template-variable"> { </span><br/><span class="hljs-template-variable"> <span class="hljs-keyword">if</span> (e.Text == "Neu") </span><br/><span class="hljs-template-variable"> { </span><br/><span class="hljs-template-variable"> // Aktion für Neu </span><br/><span class="hljs-template-variable"> }</span><span class="xml"> </span><br/><span class="xml"> else if (e.Text == "Speichern") </span><br/><span class="xml"> </span><span class="hljs-template-variable">{ </span><br/><span class="hljs-template-variable"> // Aktion für Speichern </span><br/><br/><span class="hljs-template-variable"> }</span><span class="xml"> </span><br/><span class="xml"> } </span><br/><span class="xml">} </span>
Ein User Interface mit Syncfusion
Als zweites Beispiel für die Arbeit mit Komponenten betrachten wir die Arbeit mit der Blazor-Bibliothek von Syncfusion. Auch hier starten wir wieder mit einem neuen App-Gerüst und fügen eine neue Page in Form einer Razor-Komponente hinzu. Wir haben diese vereinfachend SyncfusionTest genannt. Ergänzen Sie diese Komponente auch im Navigationsmenü, also in der Datei NavMenu.razor. Hier sehen Sie nochmals den Code:<NavLink <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"nav-link"</span> href=<span class="hljs-string">"syncfusiontest"</span>>
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"oi oi-plus"</span> <span class="hljs-attr">aria</span> <span class="hljs-attr">hidden</span>=<span class="hljs-string">"true"</span>></span> </span>
<span class="xml"> <span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>Syncfusion Test
<<span class="hljs-regexp">/NavLink> </span>
Danach kann es schon an die Einbindung der Bibliotheken für die Syncfusion-Komponenten gehen. Dazu werden mehrere Optionen angeboten. Zum einem über ein Installationsprogramm; dabei werden die Bibliotheksdateien und Beispiele kopiert. Gleichzeitig erfolgt auch eine Einbindung in Visual Studio mit eigenen Vorlagen. Diese Variante gibt es als Offline- und als Web-Installer. Zum anderen gibt es auch die Möglichkeit, die notwendigen Bibliotheken über den Paketmanager NuGet in das betreffende Projekt aufzunehmen.Gehen wir den typischen Weg über die Paketinstallation. Sie brauchen keine eigenen Paketquellen für Syncfusion. Die Bibliotheken stehen auf dem Server von NuGet zur Verfügung. Wir müssen erneut danach unterscheiden, ob wir eine Blazor-WebAssembly-App bauen oder ob wir das Hosting-Modell Blazor Server Side App verwenden. Die folgenden Schritte integrieren die Syncfusion-Komponenten in eine Blazor-WebAssembly-App:
- NuGet-Package(s) hinzufügen: Fügen wir die Bibliothek Syncfusion.Blazor hinzu. Diese beinhaltet alle angebotenen Komponenten von Syncfusion. Es gibt auch einzelne NuGet-Packages, wenn man nur die eine oder andere Komponente benötigt, also zum Beispiel Syncfusion.Blazor.Calendars (Kalender) oder Syncfusion.Blazor.Kanban (Kanban-Board). Informationen zu den einzelnen NuGet-Packages findet man in der Dokumentation bei den Komponenten beziehungsweise unter [15].
- Thema ergänzen: Danach ergänzen wir den Verweis auf das Bootstrap4-Thema in der Datei ~/wwwroot/index.html wie folgt:
<span class="hljs-tag"><<span class="hljs-name">head</span>></span>
...
<span class="hljs-tag"><<span class="hljs-name">link</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"_content/Syncfusion.Blazor.Themes/</span></span>
<span class="hljs-tag"><span class="hljs-string"> bootstrap4.css"</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> /></span>
<span class="hljs-tag"></<span class="hljs-name">head</span>></span>
- Syncfusion Service registrieren: Das geschieht in der Datei
~/Program.cs mit builder.Services.AddSyncfusionBlazor(); - Lizenzierungs-Key einfügen: Den Lizenz-Key bekommen Sie von Syncfusion online nach einer Registrierung und der Auswahl der betreffenden Komponentenbibliothek (vergleiche Bild 10). Den Lizenz-Key ergänzen Sie ebenfalls in der Datei Program.cs in der Main-Methode mit dem Eintrag Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense(“Key“);

Lizenz-Keyfür Syncfusion-Blazor-Komponente erstellen (Bild 10)
Autor
- Bibliothek importieren: Das geschieht über die @using-Anweisung in der Datei: ~/_Imports.razor durch Einbindung der Namespaces, zum Beispiel:
<span class="hljs-variable">@using</span> Syncfusion.Blazor.Buttons
<span class="hljs-variable">@using</span> Syncfusion.Blazor.Calendars
Mit diesen Schritten sind wir auch schon durch, das heißt, wir können die Komponenten in der App verwenden. Die relevanten Codeabschnitte haben wir in Listing 4 zusammengefasst.
Listing 4: Syncfusion-Komponente in Blazor-WebAssembly-App verwenden
Datei: index.html <br/><span class="hljs-meta">&lt;!DOCTYPE html&gt;</span> <br/><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span> <br/><br/><span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span> <br/> <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"utf-8"</span> /&gt;</span> <br/> <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, </span></span><br/><span class="hljs-tag"><span class="hljs-string"> initial-scale=1.0, maximum-scale=1.0, </span></span><br/><span class="hljs-tag"><span class="hljs-string"> user-scalable=no"</span> /&gt;</span> <br/> <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>MyWebApp<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span> <br/> ... <br/> <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"_content/Syncfusion.Blazor/styles/</span></span><br/><span class="hljs-tag"><span class="hljs-string"> bootstrap4.css"</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> /&gt;</span> <br/><span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span> <br/><br/>... <br/><br/><span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span> <br/><br/>Datei: Program.cs <br/>public static async Task Main(string[] args) <br/>{ <br/> // Register Syncfusion license <br/> Syncfusion.Licensing.SyncfusionLicenseProvider.<br/> RegisterLicense("Key"); <br/> var builder = <br/> WebAssemblyHostBuilder.CreateDefault(args); <br/> builder.RootComponents.Add<span class="hljs-tag">&lt;<span class="hljs-name">App</span>&gt;</span>("#app"); <br/> builder.Services.AddScoped(sp =&gt; new HttpClient <br/> { <br/> BaseAddress = <br/> new Uri(builder.HostEnvironment.BaseAddress) <br/> }); <br/><br/> builder.Services.AddSyncfusionBlazor(); <br/> await builder.Build().RunAsync(); <br/>} <br/><br/>Datei ~/_Imports.razor <br/>@using System.Net.Http <br/>... <br/>@using Syncfusion.Blazor.Buttons <br/>@using Syncfusion.Blazor.Calendars
Die Verwendung der einzelnen Komponenten in einer Page ist dann denkbar einfach, zum Beispiel ein Button und eine Kalender-Komponente:
<span class="hljs-tag"><<span class="hljs-name">SfButton</span>></span>Button<span class="hljs-tag"></<span class="hljs-name">SfButton</span>></span>
<span class="hljs-tag"><<span class="hljs-name">SfCalendar</span> <span class="hljs-attr">TValue</span>=<span class="hljs-string">"DateTime"</span>></span><span class="hljs-tag"></<span class="hljs-name">SfCalendar</span>></span>
Diese Zeilen werden dann an geeigneter Stelle einer Razor-Komponente hinzugefügt. Ein minimalistisches Beispiel mit Datenbindung zeigt Listing 5. Das Ergebnis finden Sie in Bild 11.
Listing 5: Syncfusion-Komponenten einbinden
@page <span class="hljs-string">"/syncfusiontest"</span> <br/>&lt;h3&gt;SyncfusionTest&lt;/h3&gt; <br/><br/>&lt;SfButton&gt;Button&lt;/SfButton&gt; <br/><br/>&lt;SfCalendar TValue=<span class="hljs-string">"DateTime?"</span> Value=<span class="hljs-string">"@DateValue"</span>&gt;<br/> &lt;/SfCalendar&gt; <br/><br/>@code{ <br/> <span class="hljs-keyword">public</span> DateTime? <span class="hljs-built_in">DateValue</span> { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; } = <span class="hljs-keyword">new</span> <br/> DateTime(DateTime.<span class="hljs-built_in">Now</span>.<span class="hljs-built_in">Year</span>, DateTime.<span class="hljs-built_in">Now</span>.<span class="hljs-built_in">Month</span>, <br/> <span class="hljs-number">28</span>); <br/><br/> <span class="hljs-keyword">public</span> void UpdateValue() <br/> { <br/> <span class="hljs-built_in">DateValue</span> = DateTime.<span class="hljs-built_in">Now</span>; <br/> } <br/>}

Button und Kalender-Komponentevon Syncfusion im Einsatz(Bild 11)
Autor
Auch mit Syncfusion probieren wir eine etwas umfassendere Komponente aus, beispielsweise die Kanban-Komponente. Ein komplettes Kanban-Board programmiert man nicht mal so nebenher, daher lohnt sich auch hier der Einsatz eines fertigen Bausteins.Listing 6 zeigt die Einbindung der Kanban-Komponente aus Syncfusion und Bild 12 das Ergebnis. Der Dokumentation können Sie weitere Optionen zur Erweiterung entnehmen, wie Darstellung einer Swimlane, Hinzufügen einer Sortierfunktion für die Karten, eine Drag-and-drop-Funktion und so weiter.
Listing 6: Kanban-Board mit Syncfusion-Komponente
<span class="hljs-keyword">@page</span> <span class="hljs-string">"/syncfusiontest"</span> <br/>&lt;h3&gt;SyncfusionTest&lt;/h3&gt; <br/><span class="hljs-variable">@using</span> Syncfusion.Blazor.Kanban <br/>&lt;SfKanban TValue=<span class="hljs-string">"TasksModel"</span>&gt; <br/> &lt;KanbanColumns&gt; <br/> &lt;KanbanColumn HeaderText=<span class="hljs-string">"Neu"</span> KeyField=<br/> <span class="hljs-string">"@(new List&lt;string&gt;() {"</span>Neu<span class="hljs-string">"})"</span>&gt;&lt;/KanbanColumn&gt; <br/> &lt;KanbanColumn HeaderText=<span class="hljs-string">"In Arbeit"</span> KeyField=<br/> <span class="hljs-string">"@(new List&lt;string&gt;() {"</span>In Arbeit<span class="hljs-string">"})"</span>&gt;<br/> &lt;/KanbanColumn&gt; <br/> &lt;KanbanColumn HeaderText=<span class="hljs-string">"Prüfung"</span> KeyField=<br/> <span class="hljs-string">"@(new List&lt;string&gt;() {"</span>Prüfung<span class="hljs-string">"})"</span>&gt;<br/> &lt;/KanbanColumn&gt; <br/> &lt;KanbanColumn HeaderText=<span class="hljs-string">"Beendet"</span> KeyField=<br/> <span class="hljs-string">"@(new List&lt;string&gt;() {"</span>Beendet<span class="hljs-string">"})"</span>&gt;<br/> &lt;/KanbanColumn&gt; <br/> &lt;/KanbanColumns&gt; <br/>&lt;/SfKanban&gt; <br/><br/><span class="hljs-variable">@code</span> { <br/> <span class="hljs-selector-tag">public</span> <span class="hljs-selector-tag">class</span> <span class="hljs-selector-tag">TasksModel</span> <br/> { <br/> <span class="hljs-selector-tag">public</span> <span class="hljs-selector-tag">string</span> <span class="hljs-selector-tag">Id</span> { <span class="hljs-selector-tag">get</span>; <span class="hljs-selector-tag">set</span>; } <br/> <span class="hljs-selector-tag">public</span> <span class="hljs-selector-tag">string</span> <span class="hljs-selector-tag">Title</span> { <span class="hljs-selector-tag">get</span>; <span class="hljs-selector-tag">set</span>; } <br/> <span class="hljs-selector-tag">public</span> <span class="hljs-selector-tag">string</span> <span class="hljs-selector-tag">Status</span> { <span class="hljs-selector-tag">get</span>; <span class="hljs-selector-tag">set</span>; } <br/> <span class="hljs-selector-tag">public</span> <span class="hljs-selector-tag">string</span> <span class="hljs-selector-tag">Summary</span> { <span class="hljs-selector-tag">get</span>; <span class="hljs-selector-tag">set</span>; } <br/> } <br/>}

Kanban-Boardmit Syncfusion-Komponente(Bild 12)
Autor
Empfehlung
Halten wir an dieser Stelle fest: Wir haben nahezu unendliche Optionen, um eine moderne und ansprechende Benutzeroberfläche mit Blazor zu erstellen. Jetzt gilt es, sich im „Dschungel“ der Möglichkeiten nicht zu verlaufen. Es braucht ein durchdachtes Konzept, wie man auch mit Blazor zu einem passenden User Interface kommt. Dabei stehen folgende Fragen im Mittelpunkt:- Was sind Meilensteine zum passenden User Interface?
- Welche Bibliothek soll ich verwenden?
- Kann ich Komponenten nach Belieben mischen?
Quellcode auf GitHub
Den Quellcode zu den Beispielen des Artikels finden Sie auf dem GitHub-Account der Autoren in den Repositories unter [18], [19] und [20].
Mit einer Entscheidung für eine Komponentenbibliothek gilt es zu evaluieren, ob die Anforderungen an das User Interface gemäß dem erstellten Prototyp umsetzbar sind. Das kann zum Beispiel mithilfe kleiner „Wegwerf“-Apps geschehen. Ist eine Komponentenbibliothek als geeignet eingestuft, sollte das User Interface auf der Basis dieser Bibliothek möglichst durchgängig erstellt werden.Die Vorgehensweise möchten wir noch an einem Beispiel skizzieren. Es geht um die Entwicklung eines User Interface zur Verwaltung von Stamm- und Vertragsdaten von Dozierenden einer Bildungseinrichtung. Starten wir mit einem ersten Prototyp (Bild 13). Diesen gilt es schrittweise in eine Blazor-Komponente zu überführen.

Prototypeines User Interface(Bild 13)
Autor
Wir setzen eine neue Blazor-WebAssembly-App auf. Als Komponentenbibliothek verwenden wir erneut Radzen. Der Prototyp macht deutlich, dass wir ein Tabbed-Interface (Registerkarten) benötigen. Wir werden im Abschnitt Container fündig. Die Komponente lautet <RadzenTabs/>. Die Registerkarten sind Komponenten des Typs <RadzenTabsItem/>. In dem ersten Tab fügen wir dann das Datenformular ein. Die relevanten Teile des Quellcodes findet man in Listing 7. Das erste Ergebnis sehen Sie in Bild 14. Auf dieser Basis wird das User Interface schrittweise vervollständigt.
Listing 7: Ansatz eines User Interface mit Radzen
<span class="xml">@page "/radzenTest" </span><br/><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>Dozenten<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span> </span><br/><br/><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"row"</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-7"</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">RadzenTabs</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"height: 880px"</span> </span></span><br/><span class="xml"><span class="hljs-tag"> <span class="hljs-attr">RenderMode</span>=<span class="hljs-string">"TabRenderMode.Client"</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">Tabs</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">RadzenTabsItem</span> <span class="hljs-attr">Text</span>=<span class="hljs-string">"Stammdaten"</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"row"</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-5"</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"row"</span> </span></span><br/><span class="xml"><span class="hljs-tag"> <span class="hljs-attr">style</span>=<span class="hljs-string">"margin-top:10px"</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-12"</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"salutation"</span>&gt;</span>Wählen </span><br/><span class="xml"> Sie eine Anrede:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">select</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"salutation"</span> </span></span><br/><span class="xml"><span class="hljs-tag"> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control"</span> </span></span><br/><span class="xml"><span class="hljs-tag"> <span class="hljs-attr">id</span>=<span class="hljs-string">"salutation"</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"Frau"</span>&gt;</span>Frau</span><br/><span class="xml"> <span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"Herr"</span>&gt;</span>Herr</span><br/><span class="xml"> <span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;/<span class="hljs-name">select</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"row"</span> </span></span><br/><span class="xml"><span class="hljs-tag"> <span class="hljs-attr">style</span>=<span class="hljs-string">"margin-top:10px"</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-12"</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"firstName"</span>&gt;</span>Vorname</span><br/><span class="xml"> <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">class</span>=</span></span><br/><span class="xml"><span class="hljs-tag"> <span class="hljs-string">"form-control"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"firstName"</span> </span></span><br/><span class="xml"><span class="hljs-tag"> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Vorname hier </span></span></span><br/><span class="xml"><span class="hljs-tag"><span class="hljs-string"> eingeben"</span> /&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"row"</span> </span></span><br/><span class="xml"><span class="hljs-tag"> <span class="hljs-attr">style</span>=<span class="hljs-string">"margin-top:10px"</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-12"</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"lastName"</span>&gt;</span>Nachname</span><br/><span class="xml"> <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">class</span>=</span></span><br/><span class="xml"><span class="hljs-tag"> <span class="hljs-string">"form-control"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"lastName"</span> </span></span><br/><span class="xml"><span class="hljs-tag"> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Nachname hier </span></span></span><br/><span class="xml"><span class="hljs-tag"><span class="hljs-string"> eingeben.."</span> /&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> </span><br/><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"row"</span> </span></span><br/><span class="xml"><span class="hljs-tag"> <span class="hljs-attr">style</span>=<span class="hljs-string">"margin-top:10px"</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-12"</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"email"</span>&gt;</span></span><br/><span class="xml"> E-Mail-Adresse<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">class</span>=</span></span><br/><span class="xml"><span class="hljs-tag"> <span class="hljs-string">"form-control"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"email"</span> </span></span><br/><span class="xml"><span class="hljs-tag"> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Die E-Mail-Adresse </span></span></span><br/><span class="xml"><span class="hljs-tag"><span class="hljs-string"> bitte..."</span> /&gt;</span> </span><br/><br/><span class="xml"> <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-5"</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">RadzenImage</span> <span class="hljs-attr">Path</span>=<span class="hljs-string">"img.png"</span> </span></span><br/><span class="xml"><span class="hljs-tag"> <span class="hljs-attr">Style</span>=<span class="hljs-string">"width:250px"</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">RadzenImage</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;/<span class="hljs-name">RadzenTabsItem</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">RadzenTabsItem</span> <span class="hljs-attr">Text</span>=<span class="hljs-string">"Akademisch"</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;/<span class="hljs-name">RadzenTabsItem</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">RadzenTabsItem</span> <span class="hljs-attr">Text</span>=<span class="hljs-string">"Vertrag"</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;/<span class="hljs-name">RadzenTabsItem</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;/<span class="hljs-name">Tabs</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;/<span class="hljs-name">RadzenTabs</span>&gt;</span> </span><br/><span class="xml"> <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> </span><br/><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> </span><br/><br/><span class="xml">@code </span><span class="hljs-template-variable">{ </span><br/><br/><span class="hljs-template-variable">}</span><span class="xml"> </span>

Schrittweise Umsetzungmit Blazor-Komponenten(Bild 14)
Autor
Fazit und Ausblick
Moderne User Interfaces sind für Web-Apps das A und O. Grundsätzlich bieten Webapplikationen hier alle Gestaltungsoptionen. Durch den Einsatz von Komponenten können sehr gute Ergebnisse mit vertretbarem Zeitaufwand erreicht werden. Weitere Features von Blazor stehen im abschließenden und letzten Teil unserer Artikelserie auf der Agenda.Fussnoten
- Olena Bochkor, Veikko Krypczyk, Mit .NET ins Web, Web-Apps mit Blazor, Teil 1, dotnetpro 5/2021, Seite 16 ff., http://www.dotnetpro.de/A2105BlazorLernen
- Olena Bochkor, Veikko Krypczyk, Mit .NET ins Web, Web-Apps mit Blazor, Teil 2, dotnetpro 6/2021, Seite 65 ff., http://www.dotnetpro.de/A2106BlazorLernen
- Olena Bochkor, Veikko Krypczyk, Mit .NET ins Web, Web-Apps mit Blazor, Teil 3, dotnetpro 7/2021, Seite 44 ff., http://www.dotnetpro.de/A2107BlazorLernen
- Die Blazor Component Library bei Radzen, https://razor.radzen.com
- Syncfusion, https://blazor.syncfusion.com
- Blazor UI Components by DevExpress, https://www.devexpress.com/blazor
- Telerik, https://www.telerik.com
- MatBlazor, https://www.matblazor.com
- BlazorStrap, https://blazorstrap.io
- MudBlazor, https://mudblazor.com
- BlazorFluentUI, https://github.com/BlazorFluentUI/BlazorFluentUI
- Blazor Extensions, https://github.com/BlazorExtensions
- Blazor Login Properties, https://www.radzen.com/documentation/blazor/login/#properties
- Material Icons bei Google Fonts, https://fonts.google.com/icons
- Individual NuGet packages for Syncfusion Blazor UI components, https://blazor.syncfusion.com/documentation/nuget-packages
- Material Design, https://material.io/design
- Fluent Design, https://www.microsoft.com/design/fluent
- Beispielcode Radzen, https://github.com/veikkoEF/MyWebAppRadzen
- Beispielcode Syncfusion, https://github.com/veikkoEF/MyWebAppSyncfusion
- Beispielcode Tabbed Interface, https://github.com/veikkoEF/MyWebAppTabbedInterface