Webforms Control als Blazor Componente

Da ich immer wieder gefragt werde, ob Blazor nun der Nachfolger von ASP.NET Webforms sei, der Versuch ein Webforms Server Control nachzubauen. Die Wahl fällt auf den Repeater. Zunächst einmal vom Ende her gedacht, eine Webforms Blazor Seite. Das Repeater Steuerelement folgt den Ideen des Model Binding. Also eine Select Method und der Type per Itemtype. Auch ein Itemtemplate sieht ident aus.

   1:  <table>
   2:      <Repeater ItemType="Customers" 
SelectMethod="LoadItems"
   3:                Context="Item" @ref="repeater1">
   4:          <ItemTemplate>
   5:              <tr>
   6:                  <td>@Item.CompanyName</td>
   7:              </tr>
   8:          </ItemTemplate>
   9:   
  10:      </Repeater>
  11:  </table>

Blazor typisch wird per @ref eine Code Referenz zugewiesen (die ich gar nicht nutzen werde). Das Attribut Context gibt dem Child Element den Datenzeiger mit. Natürlich fehlt der Webforms spezifische Präfix asp:

Die C# Logik ident zu Webforms

   1:  @code {
   2:  public IEnumerable<Customers> LoadItems()
   3:  {
   4:    return ef.Customers;
   5:  }

Soweit ist nun das Ziel definiert.

Die Template Platzhalter wie ItemTemplate werden per Property RenderFragment deklariert. Alles was mit dem Attribut [Parameter] versehen wird, ist dann im Blazor HTML Code als Attribute oder Element  (wie HTML Attribute) nutzbar.

Um die Liste intern zu speichern wird eine Enumerable vom Type der per ItemType eingestreut wird, erzeugt. Also Itemtype wird zu Customer.

Genauso wird die Rückgabe der Select Methode mit der generischen Liste als Rückgabe versehen. Um eine Methode als Parameter anzulegen,  Schlüsselwörter wie EventCallback (mit args), Action oder Func als Optionen. Letzteres entspricht einer Funktion also mit Rückgabe, der Customer Liste.

Initial wird die OnRenderMethode in der Blazor Komponente aufgerufen, die wiederum die SelectMethod im Parent auslöst.

   1:  @code {
   2:  int row = 0;
   3:  [Parameter]
   4:  public IEnumerable<ItemType> Items { get; set; }
   5:   
   6:  [Parameter]
   7:  public RenderFragment<ItemType> ItemTemplate { get; set; }
   8:  [Parameter]
   9:  public RenderFragment<ItemType> AlternatingItemTemplate { get; set; }
  10:  [Parameter]
  11:  public RenderFragment SeparatorTemplate { get; set; }
  12:   
  13:  [Parameter]
  14:  public Func<IEnumerable<ItemType>>SelectMethod { get; set; }
  15:   
  16:   
  17:  protected override async Task OnAfterRenderAsync(bool firstRender)
  18:   {
  19:     if (firstRender)
  20:      {
  21:             Items = SelectMethod.Invoke();
  22:              StateHasChanged();
  23:      }
  24:  }

Im HTML Part der Blazor Page muss per @TypeParam der ItemType deklariert werden. Nur damit wird die Komponente generisch und kann für jede Art von Liste genutzt werden,

Mit foreach wird durch die Customer Liste iteriert und darauf noch die Display Logik gesteuert, welches Template gerade genutz werden soll.

   1:  @typeparam ItemType
   2:   
   3:  @if (Items?.Any() ?? false)
   4:  {
   5:      @foreach (var item in Items)
   6:      {
   7:          @if (AlternatingItemTemplate == null || row % 2 == 0)
   8:          {
   9:              @ItemTemplate(item)
  10:          }
  11:          else
  12:          {
  13:              @AlternatingItemTemplate(item)
  14:          }
  15:          @if (SeparatorTemplate != null)
  16:          {
  17:              @SeparatorTemplate
  18:          }
  19:          row++;
  20:      }
  21:  }
Kommentare sind geschlossen