20
- June
2020
Posted By : Rahul
Blazor Data Binding in Depth – Part 1

In this post, we will discuss about blazor data binding in depth. This is first part of “Blazor Data Binding in Depth” article.

Introduction

Blazor is a .NET framework for building single-page applications (SPA) using C#, Razor and HTML. Data binding is one the most powerful features of any single-page application through which page UI updates with model data without page reload. We will discuss about data binding feature in Blazor.

This article is part of our step-by-step Blazor series. If you have not read our previous articles on Blazor, you can check them here.

Data Binding in Blazor is a powerful feature that allows us to synchronize a variable and a html element or a component. In simple terms, whenever a variable/property data gets update in C#, UI immediately gets update with updated data and vice-versa. Let’s see data binding types in detail.

One-Way Binding

In one-way binding, data flows in one direction only from C# code to UI. That means any property or variable in C# code directly can be used inside html and whenever this property or variable value gets update in C#, this is immediately updated in UI. However vice-versa in one-way binding is not possible. This is just to display updated model data in the UI.

Let’s understand it with the help of code example. In the following example, take a look at Counter component (counter.razor) that comes with default blazor template project.

blazor one-way data binding

In the above code, we have a private variable currentCount which is initially set to 0 that displays 0 in paragraph when application runs. The currentCount variable works as a one-way binding here. In order to bind one-way values, we use @ symbol followed by variable or property name.

A method IncrementCount is also given in the code which works as an event handler of onclick blazor event of button element. When ClickMe button will be clicked, handler will be executed and increases the currentCount value by one, which will immediately update the UI. Executing event handlers in blazor triggers a re-render which updates the UI.

You are aware now with one-way binding that updates the value in one direction only. What, if you want user to update the variable or property value from UI also. This is where two-way binding comes place.

Before understanding two-way binding in blazor, let’s understand “what are components parameters in blazor?


[Parameter] attribute in Component

A component can receive data from its parent component using [Parameter] attribute. Any of following types of data can be send to a component through [Parameter] attribute. Methods can also be send thru parameters.

  • Data
  • Events
  • Razor Content

As we saw in our previous article A deep dive on Blazor components that blazor components can be nested. That means a blazor component can be nested inside other blazor components. As an example, let’s create a new component called CounterValueDisplay.razor and nest it inside count component.

So [Parameter] attribute is used when you want to pass any data from parent (Counter) to child (CounterValueDisplay) component.

blazor data binding - component parameters

In above example, Parent (count) component is passing value to Child (CounterValueDisplay) component using [Parameter] attribute. Follow below steps for clear understanding –

Step 1. Create a public property inside child component and decorate it with [Parameter] attribute.

[Parameter]
public int CounterValue { get; set; }

Step 2. Use it as an attribute with Child component tag inside Parent component.

<CounterValueDisplay CounterValue="@currentCount"></CounterValueDisplay>

Here currentCount is a private variable in parent component that is used for one-way binding in current component and also pass the same data to child component’s parameter. Whenever Click Me button is clicked, it will update currentCount value and child component parameter value will be updated.

pass data from parent component to child component in blazor

Two-way Binding

In blazor two-way data binding, data flows in both the directions. That means from component class (C# code) to UI and from UI to component class (C# code). In above one-way binding we have seen, that currentCount value is updated from component class and displayed to UI. It cannot be updated from UI. But here in two-way binding, if user changes its value from UI, then data will be updated to component class also.

Primary use of two-way binding is in forms where you have to display existing data in UI while updating an existing record or you have to require input data from the user while inserting a new record.

Two-way binding in blazor can be achieved using a special attribute called @bind.

👉 The @bind is very powerful attribute for data binding in blazor that can be used in different forms as per the developer need.

Let’s understand multiple forms of @bind attribute with examples.

Default way of two-way binding (@bind = “Property”)

Let’s understand this simple way of two-way binding. I have added a <input> element with @bind directive and bind it to the same variable currentCount of counter component as shown in previous example.

@page "/counter"

<input type="text" @bind="currentCount" />

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}

Let’s run the application and navigate to counter component.

blazor two-way data binding in depth

As you can see in above output that when we click button, currentCount value is updated to <input> element as well and when you modify value from <input> element and tab out from the <input> element, then it reflects, then the change reflects everywhere including child component (with the help of parameter attribute explained above).

The @bind directive is smart enough 😎 that understands the control type which it has been used with. For example we used @bind directive with <input> element in above example and @bind by default binds currentCount to the Value attribute of the <input> element.

Now let’s see another example where we will use @bind with html checkbox control and create a new property.  Here you will see how @bind directive works with checkbox control and binds its checked attribute as html checkbox doesn’t have value attribute like <input> element.

<!-- Parent Component -->

<input type="checkbox" @bind="isChecked" />
<p>Checkbox checked? : @isChecked</p>

<!-- Child Component nested inside parent component -->
<CounterValueDisplay CheckBoxValue="@isChecked"></CounterValueDisplay>

@code {
    private bool isChecked = false;
}
<!-- Child Component -->

<p>Checkbox Value: @CheckBoxValue</p>

@code {
    [Parameter]
    public bool CheckBoxValue { get; set; }
}

Now let’s run the application.

blazor two-way data binding checkbox example

Two-way data binding with event (@bind = “Property” @bind:event = “Event”)

In above code of default two-way binding with <input> element example, Did you notice that modified value in <input> element did not reflect to other DOM elements until you tab out of the <input> element. Yes, this is because by default, @bind directive is actually binding the value attribute of <input> element with “currentCount” variable and also binding the “onchange” event handler which will update the “currentCount” when you tab out of the <input> element, meaning loosing focus from the <input> element.

What if you want to update the value everywhere immediately as you type and not when you lost focus from the <input> element? Yes, you can do this with the help of @bind directive with event version of two-way binding. Let’s understand this with the help of example.

<!-- Parent Component -->

<label>Change value using two-way binding with event:</label> 
<input type="text" @bind="currentCount" @bind:event="oninput" />
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

<!-- Child Component nested inside parent component -->
<CounterValueDisplay CounterValue="@currentCount"></CounterValueDisplay>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}

This way you can specify what event the @bind directive should use to update the value. As you already know, by default @bind directive works with onchange event when used with <input> element with text type and since we have specified oninput event with it, so value should update continuously as we start typing. Let’s run the application and see the output.

blazor two-way binding with event example

Two-way data binding with other attributes than Value (@bind-{ATTRIBUTE} = “Property” @bind-{ATTRIBUTE}:event = “Event”)

The @bind attribute by default binds value attribute of <input> element. If you want to bind other attributes than value, then @bind-{Attribute} syntax can be used. Let’s understand it with help of an example.

<h3>Change Paragraph Style</h3>

<input type="text" @bind="colorName" />
<br/>
<p @bind-style="ParagraphStyle" @bind-style:event="onchange">Change my color!</p>

@code {
    private string colorName = "red";
    public string ParagraphStyle
    {
        get { return $"color:{colorName}"; }
        set { colorName = value; }
    }
}

In above example,  the paragraph style is changed when colorName value changes. Let’s run the application.

blazor two-way data binding with @bind attribute

👉 By default, the @bind applies binding to the element’s onchange event (@bind=”{PROPERTY OR FIELD}”). Use @bind = “Property OR Field” AND @bind:event = “Event” to trigger binding on a different event.


Two-way data binding with format (@bind = “Property” @bind:format= “format”)

The @bind:format attribute specifies the date format to apply to the value of the <input> element. It means that it is used to format strings in data binding.

👉 Right now (at the time of this article written), @bind:format attribute works with DateTime only. This does not support other format expressions such as currency or number formats. May be, will support in future.

Let’s understand it with the help of example.

<h3>DateTimeFormatting</h3>
<input type="text" @bind="DateFrom" @bind:format="yyyy-MMM-dd" />

@code {
    private DateTime DateFrom { get; set; } = new DateTime(2020, 6, 18);
}

Let’s run the application.

blazor data binding example @bind:format

Summary (Blazor Data Binding in Depth)

In this article, we have covered –

👉 What are component parameters in Blazor?
👉 What are one-way & two-way data bindings in Blazor?
👉 How to pass data from Parent component to Child component using component parameters?
👉 Different forms of @bind attribute in two-way data binding.

In our 2nd part of Blazor Data Binding in Depth article, we will cover Blazor Event Handling and Two-way Data Binding between Components in detail.

Thank you 🙏 for reading this article. Keep Reading, Keep Growing, Keep Sharing 😃


If you found this article helpful,

BMC logoBuy me a coffee


Follow Us For Latest Posts –

Leave a Reply