Blazor is an experimental web framework that is quickly evolving. Therefore, it is possible that some of the content on this blog post is already outdated.
Data Binding in Blazor
As you might already know, most modern web frameworks (Angular, React, Vue) offer different forms of communication between a data source and the UI. This communication is known as data binding. Let’s look at the different ways you can achieve data binding with Blazor.
One-Way Data Binding
One-way data binding is also known as interpolation in other frameworks. It’s all about moving data in one direction from the “Model” to HTML elements. In @
@yourVariable
) and you’re done! Take a look at the example below to see one-way data binding in action.
Example
In the following example, an orderd list is created by iterating over a List
of strings containing the top ten automobile companies of 2018.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | @page "/top-ten" <h3>Top 10 Automobile Companies in the World</h3> <ol> @foreach (var company in autoCompanies) { <li>@company</li> } </ol> @functions{ List<string> autoCompanies { get; set; } = new List<string> { "Toyota Motor Corporation", "Volkswagen Group", "Daimler AG", "BMW", "Honda", "General Motors", "Tesla Inc.", "Ford", "Nissan", "Fiat Chrysler Automobiles" }; } |
Output

Two-Way Data Binding
In Blazor, two-way data binding is achieved with bind
bind
<input bind="@yourVariable" />
). Blazor will automatically detect changes on your HTML element and will update the variable accordingly and viceversa.
NOTE
Blazor usesthe onchange
event attribute whenthe bind
attribute is used on input elements.
For example, <input bind="@yourVariable" />
is equivalent to:
1 | <input value="@yourVariable" onchange="@((UIChangeEventArgs e) => yourVariable = e.Value.ToString())" /> |
Therefore, if you want Blazor to update your variable on every keystroke, you must use the following alternative:
1 | <input bind-value-oninput="@yourVariable" /> |
This is because, onchange
oninput
fires for every keystroke. Now, let’s look at an example of two-way data binding.
Example
In this example, three different HTML elements (<input type="text" />
<select>
<input type="checkbox" />
) use bind
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | @page "/company-form" <h2>Automobile Company Form</h2> <hr /> <label for="name">Your name:</label> <input type="text" name="name" bind-value-oninput="@name" /> <br /> <label for="favoriteCompany">Select your favorite company:</label> <select name="favoriteCompany" bind="@favoriteCompany"> @foreach (var company in autoCompanies) { <option value="@company">@company</option> } </select> <br /> <label for="promoEmails">Receive promotional emails?</label> <input type="checkbox" name="promoEmails" bind="@sendPromoEmails" /> <br /><br /> <h3>Your Information</h3> <hr /> <p>Your name: <b>@name</b></p> <p>Favorite company: <b>@favoriteCompany</b></p> <p>Send me promotional emails: <b>@sendPromoEmails.ToString()</b></p> @functions{ string name { get; set; } = string.Empty; bool sendPromoEmails { get; set; } = false; string favoriteCompany { get; set; } = "BMW"; List<string> autoCompanies { get; set; } = new List<string> { "Toyota Motor Corporation", "Volkswagen Group", "Daimler AG", "BMW", "Honda", "General Motors", "Tesla Inc.", "Ford", "Nissan", "Fiat Chrysler Automobiles" }; } |
Output

Event Binding
With Blazor you can take advantage of event-driven programming by using event binding. This is achieved with HTML event attributes likeonclick
onchange
onkeypress
onclick="@YourMethod"
). If you need to pass arguments to your method, you must use a Lambda expression (for example, onclick="@(() => YourMethod(someArgument, anotherArgument))"
). For some events, you can access event-specific arguments supported by Blazor.
Blazor supports the following event arguments:
- UIEventArgs
- UIChangeEventArgs
- UIKeyboardEventArgs
- UIMouseEventArgs
Let’s take a look at an example where onclick
Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | @page "/mouse-coordinates" <h1>Mouse pointer location</h1> <p>Mouse coordinates (X, Y): @clientX, @clientY</p> <!--Without arguments--> <button class="btn btn-primary" onclick="@ShowMouseLocation">Without event argument</button> <!--Lambda expression with one argument--> <button class="btn btn-primary ml-5" onclick="@(e => ShowMouseLocation(e))">With event argument</button> @functions { long clientX = 0; long clientY = 0; void ShowMouseLocation(UIMouseEventArgs eventArgs) { clientX = eventArgs.ClientX; clientY = eventArgs.ClientY; } } |
Output

Parent-child event callback
Sometimes you’ll want to execute something in a parent component when an event is triggered in its child component. To do that, we need to pass a callback function as a component parameter and call it from the child component when the desired event is triggered. Let’s look at an example to get a better understanding.
Example
In the parent component, you will see that two methods, IncrementCount
and ResetCount
, are being passed as component parameters to a child component.
Parent Component
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | @page "/parent-child" <h1>Parent Component</h1> <p>Child event triggered: @childEventTriggerCount time@(childEventTriggerCount != 1 ? "s" : "")</p> <ChildComponent Increment="@IncrementCount" Reset="@ResetCount"></ChildComponent> @functions{ int childEventTriggerCount = 0; void IncrementCount() { childEventTriggerCount++; this.StateHasChanged(); } void ResetCount() { childEventTriggerCount = 0; this.StateHasChanged(); } } |
In the child Increment
Reset
onclick
Child Component
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <h2>Child Component</h2> <button class="btn btn-primary" onclick="@CallParentIncrementMethod">Increment</button> <button class="btn btn-secondary" onclick="@CallParentResetMethod">Reset</button> @functions { [Parameter] Action Increment { get; set; } [Parameter] Action Reset { get; set; } void CallParentIncrementMethod() { Increment?.Invoke(); } void CallParentResetMethod() { Reset?.Invoke(); } } |
Output

Manually Trigger UI Refresh
There are some scenarios, like in the parent-child example above, where you’ll need to trigger a manual UI refresh for your components since Blazor only re-renders a component automatically if an explicit user action is made (for example, a button is clicked, a bound input field’s value changes). But fear not because the BlazorComponent.StateHasChanged
method will let you trigger a manual UI refresh when Blazor doesn’t do it automatically.
NOTE
Blazor only re-renders the component that triggers a bound event. Therefore, a parent-child event callback is one scenario where a manual UI refresh is required.
Take Away
Blazor provides one-way and two-way data binding similar to other modern web frameworks, such as Angular and Vue. You can also do event-driven programming by taking advantage of Event Bindings along with Parent-child callbacks. Blazor is still a work in progress with noticeable limitations but future versions are sure to bring exciting new features!
You can get all the examples shown on this post from our GitHub page: