Course contentsShow
← C#
Lesson 1336 of 1,90812. Modern Frontend with Razor and BlazorFree lesson

Implementing Custom Input Components

Extend base input types to create unique form controls with integrated binding.

In this lesson, you will learn how to build reusable, custom form controls in Blazor that seamlessly integrate with standard data binding and validation systems.

The Power of InputBase<T>

While Blazor provides standard inputs like <InputText> and <InputNumber>, you often need unique UI components, such as a custom star-rating selector or a masked input field. To make these work with Blazor's form infrastructure (like <EditForm>), you don't build from scratch; you inherit from the InputBase<T> class.

By inheriting from InputBase<T>, your component automatically gains the ability to participate in EditContext validation, CSS class management for error states, and two-way @bind-Value support.

Implementation Pattern

The core of your component revolves around the Value property and the ValueChanged event. You must call CurrentValueAsString or use Value directly to ensure the parent form stays in sync with your component's internal state.

Here is a simplified example of a custom checkbox-style toggle:

@inherits InputBase<bool>

<div class="toggle-container @(CurrentValue ? "on" : "off")" 
     @onclick="Toggle">
    @(CurrentValue ? "Enabled" : "Disabled")
</div>

@code {
    private void Toggle() => CurrentValue = !CurrentValue;

    protected override bool TryParseValueFromString(string value, out bool result, out string validationErrorMessage)
        => throw new NotImplementedException();
}

Key Considerations

  1. Value vs CurrentValue: When you update your component’s internal state, update CurrentValue. This property automatically triggers the ValueChanged event and marks the field as "modified" within the EditContext, which is essential for validation.
  2. CSS Integration: InputBase<T> provides an EditContext that automatically tracks validation status. You can access CssClass to append is-invalid or is-valid styles to your custom HTML elements automatically based on whether the form state is valid.
  3. Parsing: If your input handles complex types, you must override TryParseValueFromString. For simple toggles or booleans, you can often leave this unused, provided you handle the logic via CurrentValue.

By extending InputBase<T>, you ensure your custom components behave exactly like native Blazor inputs, maintaining consistency across your application's forms.

Key Takeaway: By inheriting from InputBase<T>, you bridge your custom UI logic with Blazor’s validation and binding systems, allowing your unique components to function as first-class citizens in any EditForm.