Extend, Customize, and Reuse Components
29 Nov 202414 minutes to read
The Blazor framework provides the support to extend a component or customize it within another component for a strong composite model.
Extend Syncfusion® Blazor component
The Syncfusion® Blazor components can extend and customize the logic by creating a new Blazor component.
-
Right-click on the
~/Pages
folder in the Visual Studio and selectAdd -> Razor Component
to create a new Razor component (SyncButton.razor). -
Inherit any Syncfusion® Blazor component and render your component based on your logic with Syncfusion® Blazor API.
@inherits SfButton; <button class="@className" disabled="@Disabled">@Content</button> @code { private string className = "btn"; [Parameter] public ButtonStyles Styles { get; set; } public enum ButtonStyles { Basic, Success, Info, Warning, Danger } protected override void OnInitialized() { base.OnInitialized(); ApplyStyles(); } private void ApplyStyles() { if (IsPrimary) { className += " btn-primary"; } else if (Styles == ButtonStyles.Success) { className += " btn-success"; } else if (Styles == ButtonStyles.Info) { className += " btn-info"; } else if (Styles == ButtonStyles.Warning) { className += " btn-warning"; } else { className += " btn-danger"; } } }
-
Render your new component in the view page
~/Pages/Home.razor or Index.razor
and run the application.<SyncButton Content="Primary" IsPrimary="true" Disabled="true"></SyncButton> <SyncButton Content="Success" Styles="SyncButton.ButtonStyles.Success"></SyncButton> <SyncButton Content="Info" Styles="SyncButton.ButtonStyles.Info"></SyncButton> <SyncButton Content="Warning" Styles="SyncButton.ButtonStyles.Warning"></SyncButton> <SyncButton Content="Danger" Styles="SyncButton.ButtonStyles.Danger"></SyncButton>
Use Syncfusion® Blazor component within another Blazor component
The Syncfusion® Blazor component can be implemented within another Blazor component.
-
Right-click on the
~/Pages
folder in the Visual Studio and selectAdd -> Razor Component
to create a new Razor component (TodoList.razor). -
Add any Syncfusion® Blazor component to the newly created Blazor component.
<h3>Todo List</h3> @using Syncfusion.Blazor.Inputs; @using Syncfusion.Blazor.Buttons; @using Syncfusion.Blazor.Lists; <div class="form-group"> <SfTextBox @oninput="UpdateItem" @bind-Value="@item" Placeholder="Add new item" Width="200px"></SfTextBox> <SfButton @onclick="AddItem">Add</SfButton> </div> @if (items.Count > 0) { <SfListView DataSource="@items"> <ListViewFieldSettings TValue="ItemModel" Id="Id" Text="Text"></ ListViewFieldSettings> </SfListView> } @code { private string item; private List<ItemModel> items = new List<ItemModel>(); private void UpdateItem(Microsoft.AspNetCore.Components.ChangeEventArgs args) { item = args.Value.ToString(); } // Add new items on button click. private void AddItem() { if (item != null && item.Length > 0) { var newItem = new ItemModel(items.Count + 1, item); items.Add(newItem); item = null; } } // List view data source model. public class ItemModel { public ItemModel(int id, string text) { Id = id; Text = text; } public int Id { get; set; } public string Text { get; set; } } }
-
Render your new component in the view page
~/Pages/Home.razor or Index.razor
and run the application.<TodoList></TodoList>
Render Syncfusion® Blazor component dynamically
The following methods can be used to render the Syncfusion® Blazor components dynamically:
- RenderFragment with Razor Template Syntax
- RenderFragment with RenderTreeBuilder methods
- BuildRenderTree method
RenderFragment with Razor Syntax
The RenderFragment
represents the segments of UI content that can be reused in the view page based on the application logic.
You can use Razor Template Syntax to define the RenderFragment
in the view page.
The following code demonstrates the RenderFragment that renders the SfButton
component.
@{
RenderFragment<string> ButtonFragment = content =>
@<SfButton>@content</SfButton>;
}
@ButtonFragment("My Button")
The following code demonstrates the RenderFragment that renders the SfGrid
component.
@{
RenderFragment<List<Order>> GridFragment = dataModel =>
@<SfGrid DataSource="@dataModel"></SfGrid>;
}
@GridFragment(orders)
@code {
private List<Order> orders { get; set; }
public class Order
{
public int? OrderID { get; set; }
public string CustomerID { get; set; }
}
protected override void OnInitialized()
{
orders = Enumerable.Range(1, 5).Select(x => new Order()
{
OrderID = 1000 + x,
CustomerID = (new string[] { "ALFKI", "ANANTR", "ANTON", "BLONP", "BOLID" })[new Random().Next(5)]
}).ToList();
}
}
RenderFragment with RenderTreeBuilder methods
You can define the RenderFragment delegate with RenderTreeBuilder’s methods.
NOTE
Refer to Manual RenderTreeBuilder logic to know more about RenderTreeBuilder.
@RenderSfButton()
@code {
private RenderFragment RenderSfButton()
{
RenderFragment button = b =>
{
b.OpenComponent<SfButton>(0);
b.AddAttribute(1, "Content", "My Button");
b.CloseComponent();
};
return button;
}
}
You can render the nested components by using RenderFragment
.
<SfChip>
<ChipItems>
@RenderChipItem("Apple")
@RenderChipItem("Banana")
@RenderChipItem("Mango")
</ChipItems>
</SfChip>
@code {
private RenderFragment RenderChipItem(string text)
{
RenderFragment chipItem = b =>
{
b.OpenComponent<ChipItem>(0);
b.AddAttribute(1, "Text", text);
b.CloseComponent();
};
return chipItem;
}
}
BuildRenderTree method
The BuildRenderTree
is an override method that can be used to render a reusable component dynamically.
Suppose, if you want to add multiple text-boxes in your application with the same properties and values, you may feel like the code is repeatedly used. For example, the below form component has similar textbox settings and is wrapped with a bootstrap form-group
class.
<div class="form-group">
<label for="first-name">First Name:</label>
<SfTextBox ID="first-name" CssClass="e-small" Autocomplete="AutoComplete.Off" ShowClearButton="true" Width="250px"></SfTextBox>
</div>
<div class="form-group">
<label for="last-name">Last Name:</label>
<SfTextBox ID="last-name" CssClass="e-small" Autocomplete="AutoComplete.Off" ShowClearButton="true" Width="250px"></SfTextBox>
</div>
<div class="form-group">
<label for="address">Address:</label>
<SfTextBox ID="address" CssClass="e-small" Autocomplete="AutoComplete.Off" ShowClearButton="true" Width="250px"></SfTextBox>
</div>
<div class="form-group">
<label for="age">Age:</label>
<SfTextBox ID="age" CssClass="e-small" Autocomplete="AutoComplete.Off" ShowClearButton="true" Width="250px"></SfTextBox>
</div>
<div class="form-group">
<label for="city">City:</label>
<SfTextBox ID="city" CssClass="e-small" Autocomplete="AutoComplete.Off" ShowClearButton="true" Width="250px"></SfTextBox>
</div>
<div class="form-group">
<label for="country">Country:</label>
<SfTextBox ID="country" CssClass="e-small" Autocomplete="AutoComplete.Off" ShowClearButton="true" Width="250px"></SfTextBox>
</div>
You can create a simple Blazor component with the BuildRenderTree
method and get the repeated properties in a Dictionary
field and reuse it.
-
Right-click on the
~/Pages
folder in the Visual Studio and selectAdd -> Class
to create a new class file (SyncTextBox.cs). -
Inherit the newly created class with ComponentBase and override the BuildRenderTree method to create the component.
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Rendering; using Syncfusion.Blazor.Inputs; using System.Collections.Generic; namespace InputValidationApp.Pages { public class SyncTextBox : ComponentBase { [Parameter] public string ID { get; set; } [Parameter] public string Label { get; set; } [Parameter] public Dictionary<string, object> TextAttributes { get; set; } protected override void BuildRenderTree(RenderTreeBuilder builder) { // create div element. builder.OpenElement(0, "div"); builder.AddAttribute(1, "class", "form-group"); // creating label element. builder.OpenElement(2, "label"); builder.AddAttribute(3, "for", ID); builder.AddContent(4, Label); builder.CloseElement(); // create Syncfusion TextBox component. builder.OpenComponent<SfTextBox>(5); builder.AddAttribute(6, "ID", ID); // Added similar attributes used in the component. if (TextAttributes != null) { builder.AddMultipleAttributes(3, TextAttributes); } builder.CloseComponent(); builder.CloseElement(); } } }
-
Now, render the new reusable Blazor component in the
~/Pages/Home.razor or Index.razor
page and run the application.<SyncTextBox ID="first-name" Label="First Name:" TextAttributes="@textAttributes"></SyncTextBox> <SyncTextBox ID="last-name" Label="Lat Name:" TextAttributes="@textAttributes"></SyncTextBox> <SyncTextBox ID="address" Label="Address:" TextAttributes="@textAttributes"></SyncTextBox> <SyncTextBox ID="age" Label="Age:" TextAttributes="@textAttributes"></SyncTextBox> <SyncTextBox ID="city" Label="City:" TextAttributes="@textAttributes"></SyncTextBox> <SyncTextBox ID="country" Label="Country:" TextAttributes="@textAttributes"></SyncTextBox> @code { public Dictionary<string, object> textAttributes { get; set; } = new Dictionary<string, object>() { { "CssClass", "e-small" }, { "Autocomplete", AutoComplete.Off }, { "Width" , "250px" }, { "ShowClearButton", true } }; }
NOTE
The advantages of a reusable component are:
1. Instead of changing values in each component, you can change a property value once and it will be reflected in all the components.
2. Better code optimization against the repeated code.