Introduction
Blazor is a new framework built by Microsoft for creating interactive client-side web UI with a .NET codebase. We can write both client-side and server-side code in C#.NET itself. I have already written five articles about the Blazor server on C# Corner. Please refer to the below articles for more basics about the Blazor framework.
Components are implemented in Razor component files (. razor) using a combination of C# and HTML markup. A component in Blazor is formally referred to as a Razor component.
We can create a child component and reuse it in another component. We will share data between these components very easily. We will create a custom textbox as a child component. This custom textbox will show the current character count in the textbox and will restrict the total number of characters if needed. I will explain all the actions step by step.
Create Blazor application in Visual Studio 2019
Choose the Blazor template from Visual Studio 2019 and create a Blazor application.
We can create a new razor component inside the “Pages” folder.
We can define the HTML markup in the component.
<div class="float-right">
<i>Total Characters : @TextLength/@LengthString</i>
</div>
<div class="form-group row mb-2">
<label class="col-md-3 col-form-label" for="Name">@FieldName</label>
<div class="col-md-7">
<input class="form-control" type="text" placeholder="@FieldName" value="@Value" @oninput="OnValueChanged" maxlength="@MaxLength" />
</div>
</div>
We can add the C# code also inside the @code block.
@code {
[Parameter]
public string Value { get; set; }
[Parameter]
public string FieldName { get; set; }
[Parameter]
public int MaxLength { get; set; } = -1;
[Parameter]
public EventCallback<string> ValueChanged { get; set; }
string LengthString;
int TextLength;
protected override void OnInitialized()
{
TextLength = Value.Length;
LengthString = (MaxLength == -1) ? "Unlimited" : MaxLength.ToString();
}
private Task OnValueChanged(ChangeEventArgs e)
{
Value = e.Value.ToString();
TextLength = Value.Length;
return ValueChanged.InvokeAsync(Value);
}
}
We have defined three parameter properties “Value”, “FieldName” and “MaxLength”.
FieldName is used for displaying the field name and placeholder value in the custom textbox. MaxLength is used to restrict maximum characters in the custom textbox if needed. FieldName and MaxLength properties in Blazor act as @Input decorators in Angular. These properties are used to share data from the parent component to the child component. Value property acts as @Output decorator in Angular. This will be used for sharing data back from the child component to the parent component. In Angular, we use EventEmitter along with Output decorators to share data from child to parent component. In Blazor, we use the “EventCallback” parameter to emit value from the child component to the parent component. Please note, the “Changed” suffix is added to the value property parameter. This is the default convention used in Blazor.
We have created an “OnValueChanged” method and bound it with the “@oninput” attribute of input control in HTML markup.
CustomTextbox.razor
<div class="float-right">
<i>Total Characters : @TextLength/@LengthString</i>
</div>
<div class="form-group row mb-2">
<label class="col-md-3 col-form-label" for="Name">@FieldName</label>
<div class="col-md-7">
<input class="form-control" type="text" placeholder="@FieldName" value="@Value" @oninput="OnValueChanged" maxlength="@MaxLength" />
</div>
</div>
@code {
[Parameter]
public string Value { get; set; }
[Parameter]
public string FieldName { get; set; }
[Parameter]
public int MaxLength { get; set; } = -1;
[Parameter]
public EventCallback<string> ValueChanged { get; set; }
string LengthString;
int TextLength;
protected override void OnInitialized()
{
TextLength = Value.Length;
LengthString = (MaxLength == -1) ? "Unlimited" : MaxLength.ToString();
}
private Task OnValueChanged(ChangeEventArgs e)
{
Value = e.Value.ToString();
TextLength = Value.Length;
return ValueChanged.InvokeAsync(Value);
}
}
We can add this child component inside a parent component. We can create a new parent component.
ParentComponent.razor
@page "/parentcomponent"
<CustomTextbox @bind-Value="name" FieldName="Name" MaxLength="20" />
<CustomTextbox @bind-Value="address" FieldName="Address" />
@code {
string name = "Sarath Lal";
string address = "Kakkanad";
}
We have added two custom textbox child components inside this parent component. “@bind-{parametername}” is used for binding the child component field with the parent component field. Here, “Value” is the field name in the child component. So, we used this as “@bind-Value”. We can pass these two input parameters “FieldName” and “MaxLength” from the parent component. I have not passed the MaxLength property for the second child component. Hence, the default value -1 will be assigned to this component in run time.
We can modify the shared component “NavMenu” to add a navigation to the parent component.
NavMenu.razor
<div class="top-row pl-4 navbar navbar-dark">
<a class="navbar-brand" href="">BlazorReusableComponent</a>
<button class="navbar-toggler" @onclick="ToggleNavMenu">
<span class="navbar-toggler-icon"></span>
</button>
</div>
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
<ul class="nav flex-column">
<li class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="oi oi-home" aria-hidden="true"></span> Home
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="counter">
<span class="oi oi-plus" aria-hidden="true"></span> Counter
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="fetchdata">
<span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="parentcomponent">
<span class="oi oi-list-rich" aria-hidden="true"></span> Parent Component
</NavLink>
</li>
</ul>
</div>
@code {
bool collapseNavMenu = true;
string NavMenuCssClass => collapseNavMenu ? "collapse" : null;
void ToggleNavMenu()
{
collapseNavMenu = !collapseNavMenu;
}
}
We can run the application.
You can notice that a new “Parent Component” link appears in the menu. You can click that link to see the parent component.
We have defined two custom textbox components inside the parent component. For the first textbox, we have given a 20-character limit and for the second component, no character limit is given. So that, you can enter unlimited characters in the second textbox. The total character count is also visible on the screen.
Conclusion
In this post, we have created a reusable child component in Blazor and easily used in another parent component. We have shared the data from the parent component with the child component and vice versa also.