Was soll ich sagen. Blazor Komponenten mag ich von Tag zu Tag mehr. Ich habe schon viele UI Frameworks genutzt, aber praktisch immer die Finger von UI Elementen gelassen, die nicht out of the Box mitgeliefert wurden. Aber Blazor setzt voll auf HTML und CSS und ist insofern die Schleifmaschine fürs Web. Es gibt ein sehr verbreitetes Framework, Bootstrap 4. Darin enthalten ein modaler Dialog. Funktioniert praktisch ohne JavaScript codieren zu müssen. Aber am Ende ist Bootstrap auch ein JS Framework. Der Artikel zeigt wie man die Bootstrap CSS Layout Klassen trotzdem verwenden kann. Nur mit C#
Bootstrap Basics
Bevor man loslegt, zuerst ein Blick in Boostrap. Das Modale Fenster liegt vor einem ausgegrautem Hintergrund.
Wie löst Boostrap das? Der graue Bereich ist ein Div mit der Klasse modal-backdrop. Der Dialog kommt aus Bootstrap mit Header, Body und Footer. Wichtig ist die CSS Klasse show, die normalerweise per JavaScript an und ausgeschalten wird.
1: <div class="modal fade show" id="myModal" style=" display: block;">
2: <div class="modal-dialog">
3: <div class="modal-content">
4: <div class="modal-header">
5: <h4 class="modal-title">Modal Heading</h4>
6: <button type="button" class="close" data-dismiss="modal">×</button>
7: </div>
8: <div class="modal-body">
9: Modal body..
10: </div>
11: <div class="modal-footer">
12: <button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
13: </div>
14: </div>
15: </div>
16: </div>
17: </div>
18: <div class="modal-backdrop fade show"></div>
Component ChildContent
Das besondere an HTML ist die Möglichkeit das DOM tief zu schachteln. Genau diese Funktion ist nach wie vor auch mit Blazor vorhanden. Meist wird das als Template oder Itemtemplate bezeichnet. In Blazor wird ein Property ChildContent vom Typ Renderfragment benötigt. Der Name ist in dem Fall zwingend. Genauso zwingend wie die Blazor typische Attribuierung mit [Parameter] wenn man aus dem HTML Code per Attribut ins Property rein will.
Es wird also eine Razor Komponente angelegt, hier als ModalBootstrap.razor bezeichnet. Die weiteren Attribute ala Title und co dienen steuern später den Inhalt des Popup Dialoges. Mit der Methode Show wird der Dialog angezeigt oder versteckt. Der Besondere Trick steckt im OnClick Event, das ein Konsument abonnieren kann und so auf beliebige Ereignisse dort Code Logik implementiert. Dies hier nur optional.
1: @code {
2: private Boolean _Show { get; set; }
3: [Parameter]
4: public string Title { get; set; }
5:
6: [Parameter]
7: public RenderFragment ChildContent { get; set; }
8:
9: [Parameter]
10: public EventCallback<MouseEventArgs> OnClick { get; set; }
11:
12: public void Show()
13: {
14: _Show =! _Show;
15: }
16:
17: }
Der HTML Part in der gleichen Razor Seite führt die Logik und das Bootstrap Layout zusammen. Der HTML Block wird nur gerendert, wenn Show das so möchte. Der ChildContent wird dann vom Komponenten Aufrufer als HTML definiert.
1: @if (_Show)
2: {
3: <div class="modal fade show" id="myModal" style=" display: block;">
4: <div class="modal-dialog">
5: <div class="modal-content">
6: <div class="modal-header">
7: <h4 class="modal-title">@Title</h4>
8: <button type="button" class="close" data-dismiss="modal" @onclick="Show">×</button>
9: </div>
10: <div class="modal-body">
11: @ChildContent
12: </div>
13: <div class="modal-footer">
14: <button type="button" class="btn btn-danger" data-dismiss="modal" @onclick="Show">Close</button>
15: </div>
16: </div>
17: </div>
18: </div>
19: <div class="modal-backdrop fade show"></div>
20: }
Component einbinden
Auch wenn es einfach aussieht, bis ich dort war haben ich doch mehr Zeit aufgewendet als man auf den ersten Blick glauben würde. Dagegen ist die dotnet core Razor Seite ein Klacks. Auch dazu wird eine Razor Component in dotnet core 3 Visual Studio Projekt hinzugefügt. Unsere Komponente wird wie ein HTML Element samt Title Attribut erstellt. Um im C# Code auf das Element zugreifen zu können, wird der Kniff mit @ref angewandt, das per Namen auf das Property im Code verweist. Damit lässt sich dann Show aufrufen. Netter Nebeneffekt Nummer 2 ist, das der Childcontent zur Page gehört und so auch das Blazor Binding an das Page Model bindet. Also das Input Feld hängt direkt an der Eigenschaft daten.
1: <ModalBootstrap @ref="modal1" Title="Daten eingabe">
2: <p>das ist mein Content
3: </p>
4: test <input @bind="daten"/>
5: </ModalBootstrap>
6: <button @onclick="openmodal">show</button>
7: @daten
8:
9: @code {
10: public string daten { get; set; }
11: ModalBootstrap modal1;
12: void openmodal()
13: {
14: modal1.Show();
Im Vergleich zu Boostrap fehlt nur noch die smoothe Animation (Fade in out). Es fehlt mir grad auch noch die Idee wie ich das realisieren werde. Kommt aber sicher in einem weiteren Blazor Blog Eintrag. Zwischenzeitlich biete ich auch Blazor Training bei ppedv an.