Introduction
This is the second part of the series Blazor Bindings By Example in which we explore how to bind some of the properties in our example model, which we created in part 1 of this series.
In this part we look at binding string properties, namely the Name property.
As a reminder our model looks like this:
namespace BlazorBindingExamples.Models
{
public class Model
{
public Model(Guid id)
{
Id = id;
}
public Guid Id { get; init; }
public string? Name { get; set; }
public Gender? Gender { get; set; }
public string? Nationality { get; set; }
public int? Age { get; set; }
public decimal? Salary { get; set; }
public MarketingOption? MarketingOptions { get; set; }
}
}
All the code for this series is available from GitHub.
Extend Visual Studio Project
First of all, let's extend the Visual Studio example project to include a new page dedicated to various ways to bind the Name property and add a left 'NavLink' item.
Add a new Page
called "StringBinding" for both the view and the viewmodel:
- Pages/StringBinding.razor
- Pages/StringBinding.razor.cs
And then add a new NavLink
entry within the shared NavMenu
below the existing "Home" menu:
- Shared/NavMenu.razor
StringBinding.razor
@page "/stringbinding"
<PageTitle>Blazor Bindings By Example - String Binding</PageTitle>
<h1>Blazor Example Bindings - String Binding</h1>
@if (!Initialised)
{
<p>Loading...</p>
}
else
{
<!-- Put the binding examples here //-->
}
StringBinding.razor.cs
using BlazorBindingExamples.Models;
using Microsoft.AspNetCore.Components;
namespace BlazorBindingExamples.Pages
{
public partial class StringBinding : ComponentBase
{
public bool Initialised { get; set; } = false;
public Model Model { get; private set; }
protected override async Task OnInitializedAsync()
{
Model = new(Guid.NewGuid());
Model.Name = "Stuart Wells";
await base.OnInitializedAsync();
// Set this when fully initialised as we use this to prevent premature rendering
Initialised = true;
}
}
}
NavMenu.razor
<div class="nav-item px-3">
<NavLink class="nav-link" href="stringbinding">
<span class="oi oi-signpost" aria-hidden="true"></span> String Binding
</NavLink>
</div>
Binding The Name Property
The Name property is a nullable string which is read/write:
public string? Name { get; set; }
It has been initialised with my name, "Stuart Wells", and can be bound in multiple ways:
- read-only element content
- read-only attribute content
- conditional read-only content
- editable input field
Element Content
Bind the string value to a simple read-only html element content such as a paragraph <p>
or <span>
in line using the @Model
reference:
@Model.Name
An example in a paragraph would be:
<p>The name of the client is '@Model.Name'.</p>
Which would present as:
The name of the client is 'Stuart Wells'.
Tip: if you find yourself wanting to use the @ character, you can escape this t prevent it being interpreted as a viewmodel reference by prefixing it with another @:
<p>The variable @@Model.Name contains the value "@Model.Name".</p>
Produces
The variable @@Model.Name contains the value "Stuart Wells".
Attribute Content
Bind the string value to a read-only html attribute content such as a paragraph title <p title="">
using the @Model
reference:
<p title="About @Model.Name">The title contain the value of the Name property.</p>
Which could look like this, with the tooltip showing the title:
Conditional Content
Sometimes the content we need to write out may need some conditional logic. One could argue here that we should not be using conditional logic like this in the view anyway and that any logic should be in the viewmodel and the view should just bind the result, but for demonstration purposes we can bind script expressions
inline like this:
<p title="@(string.IsNullOrWhiteSpace(Model.Name) ? "Unknown Name" : "About " + Model.Name )">
The property Name does @(string.IsNullOrWhiteSpace(Model.Name) ? "not " : string.Empty ) have a value.
</p>
Which produces this when we have a value:
And this when we don't have a value:
Editable Input
So far we have seen how to bind in a property that is read-only. If the underlying property value changes, the read-only value will update, but we need to have a two-way binding using an input field to capture the change.
Using an input field on its own (outside a form) the value will bind when the field is exited (loses focus) or enter/return is pressed:
<label for="opt4">Name:</label>
<input id="opt4" type="text" @bind-value="Model.Name">
<p>The value of Name is "@Model.Name".</p>
Which produces
Summary
In this article, the second article in the series "Blazor Bindings By Example", we have examine how a simple string property can be bound to html content and how it can be edited using two-way bindings.
In the next article, we will examine the Gender property, which is an enumeration.