Do you use @bind-Value:after instead of ValueChanged?
When using two-way binding in Blazor with @bind-Value
, you might want to execute code when the bound value changes. A common mistake is trying to use both @bind-Value
and ValueChanged
together, but this causes a compile error because ValueChanged
is generated by the @bind-Value
directive.
The correct approach is to use @bind-Value:after
which triggers a callback after the value changes.
❌ Bad Example - Using ValueChanged with @bind-Value
<RadzenRadioButtonList TValue="bool?"
@bind-Value="Question.Answer.BoolValue"
ValueChanged="@(() => SaveQuestion())" />
Figure: Bad example - This gives a compile error: "The component parameter 'ValueChanged' is used two or more times for this component ... The component parameter 'ValueChanged' is generated by the '@bind-Value' directive attribute
✅ Good Example - Using @bind-Value:after
<RadzenRadioButtonList TValue="bool?"
@bind-Value="Question.Answer.BoolValue"
@bind-Value:after="@(() => SaveQuestion())" />
Figure: Good example - Using @bind-Value:after gives you two-way binding and control over what code is called when the value changes
How @bind-Value:after works
The @bind-Value:after
directive:
- Executes after the bound value is assigned synchronously
- Supports both synchronous and asynchronous delegates
- Works with any component that supports two-way binding
- Can be used with different binding events (e.g.,
@bind-Value:event="oninput"
)
Advanced Example
<input @bind="searchText"
@bind:event="oninput"
@bind:after="PerformSearch" />
@code {
private string? searchText;
private string[]? searchResult;
private async Task PerformSearch() =>
searchResult = await SearchService.FetchAsync(searchText);
}
Figure: Good example - Using @bind:after with input elements for real-time search