Blazor アプリケーションでデータにコントロールをバインドする

完了

Blazor では、HTML コントロールをプロパティにバインドして、値の変更がユーザー インターフェイス (UI) に自動的に表示されるようにすることができます。

たとえば、お客様のピザの好みに関する情報を収集するページを開発しているとします。 データベースから情報を読み込み、お客様がお気に入りのトッピングの記録などの変更を行えるようにします。 ユーザーからの変更やデータベース内の更新があった場合は、できるだけ早く新しい値を UI に表示させる必要があります。

このユニットでは、Blazor でデータ バインディングを使用して、UI 要素をデータ値、プロパティ、または式に関連付ける方法について説明します。

データ バインディングとは何ですか。

HTML 要素で値を表示する場合、表示を変更するコードを記述できます。 値が変更された場合に表示を更新するには、追加のコードを記述する必要があります。 Blazor では、データ バインディングを使用して、HTML 要素をフィールド、プロパティ、または式に接続できます。 このようにすると、値が変更されたときに、HTML 要素が自動的に更新されます。 更新は通常、変更後すぐに行われ、更新コードを記述する必要はありません。

コントロールをバインドするには、@bind ディレクティブを使います。

@page "/"

<p>
    Your email address is:
    <input @bind="customerEmail" />
</p>

@code {
    private string customerEmail = "user@contoso.com"
}

前のページでは、customerEmail 変数の値が変更されるたびに、<input> の値が更新されます。

Note

<input> などのコントロールでは、コンポーネントがレンダリングされたときにのみ表示が更新され、フィールドの値が変更されたときは更新されません。 Blazor コンポーネントは、イベント ハンドラーのコードが実行された後にレンダリングされるため、実際の更新は通常すぐに表示されます。

特定のイベントに要素をバインドする

@bind ディレクティブはスマートであるため、使用するコントロールを認識しています。 たとえば、値を <input> にバインドすると、value 属性がバインドされます。 HTML のチェックボックス <input> には、value 属性ではなく checked 属性があります。 @bind 属性では、代わりにこの checked 属性が自動的に使用されます。 既定で、コントロールは DOM onchange イベントにバインドされています。 たとえば、次のページを考えてみます。

@page "/"

<h1>My favorite pizza is: @favPizza</h1>

<p>
    Enter your favorite pizza:
    <input @bind="favPizza" />
</p>

@code {
    private string favPizza { get; set; } = "Margherita"
}

ページがレンダリングされると、既定値の Margherita<h1> 要素とテキストボックスの両方に表示されます。 テキストボックスに新しいお気に入りのピザを入力したとき、Tab でテキストボックスを離れるか、Enter キーを押すまで、<h1> 要素は変更されません。そのときに、onchange DOM イベントが発生するためです。

多くの場合、それが目的の動作になります。 ただし、テキストボックスに何らかの文字を入力するとすぐに <h1> 要素を更新させたいとします。 この結果を得るには、代わりに、oninput DOM イベントにバインドします。 このイベントにバインドするには、@bind-value ディレクティブと @bind-value:event ディレクティブを使用する必要があります。

@page "/"

<h1>My favorite pizza is: @favPizza</h1>

<p>
    Enter your favorite pizza:
    <input @bind-value="favPizza" @bind-value:event="oninput" />
</p>

@code {
    private string favPizza { get; set; } = "Margherita"
}

この例では、テキストボックスに何らかの文字を入力するとすぐにタイトルが変更されます。

バインドされた値の書式を設定する

ユーザーに日付を表示する場合、ローカライズされたデータ形式を使いたいことがあります。 たとえば、日を最初にした日付の記述を好む英国のユーザー専用のページを作成するとします。 @bind:format ディレクティブを使用して、1 つの日付書式文字列を指定できます。

@page "/ukbirthdaypizza"

<h1>Order a pizza for your birthday!</h1>

<p>
    Enter your birth date:
    <input @bind="birthdate" @bind:format="dd-MM-yyyy" />
</p>

@code {
    private DateTime birthdate { get; set; } = new(2000, 1, 1);
}

Note

記述するときに、書式文字列は日付値でのみサポートされます。 通貨の書式、数値の書式などは将来追加される可能性があります。 バインドの書式に関する最新情報を確認するには、Blazor のドキュメントの「書式指定文字列」を参照してください。

@bind:format ディレクティブを使用する代わりに、バインドされた値を書式設定する C# コードを記述することもできます。 次の例のように、メンバー定義で get アクセサーと set アクセサーを使用します。

@page "/pizzaapproval"
@using System.Globalization

<h1>Pizza: @PizzaName</h1>

<p>Approval rating: @approvalRating</p>

<p>
    <label>
        Set a new approval rating:
        <input @bind="ApprovalRating" />
    </label>
</p>

@code {
    private decimal approvalRating = 1.0;
    private NumberStyles style = NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign;
    private CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US");
    
    private string ApprovalRating
    {
        get => approvalRating.ToString("0.000", culture);
        set
        {
            if (Decimal.TryParse(value, style, culture, out var number))
            {
                approvalRating = Math.Round(number, 3);
            }
        }
    }
}

次のユニットでは、学習した内容を適用します。