データバインディングとイベント処理
一方向および双方向のデータバインディングを適用し、DOMとコンポーネントのイベントを処理して、EventCallbackを使います。
「データバインディングとイベント処理」はCoddyKit上の無料C# Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC# Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C# Academyコースには全4レッスンが含まれています。
Blazor のバインディング
Blazor は3種類のバインディング方向をサポートしています。一方向(読み取り専用、@expr)、イベントベース(@onclick など)、双方向(@bind)です。これらを組み合わせることで、リアクティブ UI の基盤を構成します。
一方向データバインディング
@ を使って、マークアップ内に C# 式をそのまま出力します。値はコンポーネントが再レンダリングされるたびに更新されますが、DOM から C# へ値を送り返すことはできません。
<!-- One-way: C# -> DOM -->
<p>Count: @_count</p>
<p>Full name: @($"{_firstName} {_lastName}")</p>
<p>Price: @Price.ToString("C")</p>
@code {
private int _count = 0;
private string _firstName = "Alice";
private string _lastName = "Smith";
[Parameter] public decimal Price { get; set; }
}@bind による双方向バインディング
@bind は、プロパティの設定と変更イベントの両方を使って、入力要素をフィールドに接続します。テキスト、数値、日付、チェックボックス、セレクトで使用できます。
<input @bind="_name" placeholder="Enter name" />
<input type="number" @bind="_quantity" />
<input type="date" @bind="_dueDate" />
<input type="checkbox" @bind="_isActive" />
<p>Name: @_name | Qty: @_quantity | Active: @_isActive</p>
@code {
private string _name = "";
private int _quantity = 1;
private DateTime _dueDate = DateTime.Today;
private bool _isActive = true;
}カスタムイベントでの @bind
デフォルトでは、@bind は onchange イベントを使用します。@bind:event を使うとイベントを変更できます。たとえば oninput はキー入力のたびに発生するため、ライブ検索に適しています。
@* Updates on every keystroke instead of on focus-loss *@
<input @bind="_search"
@bind:event="oninput"
placeholder="Live search..." />
<ul>
@foreach (var item in Filtered)
{
<li>@item</li>
}
</ul>
@code {
private string _search = "";
private string[] Items = { "Apple", "Banana", "Cherry", "Avocado" };
private IEnumerable<string> Filtered =>
Items.Where(i => i.Contains(_search, StringComparison.OrdinalIgnoreCase));
}@onclick によるイベント処理
@onclick(およびその他の DOM イベントディレクティブ)を使って、C# のデリゲートを DOM イベントに関連付けます。同期メソッドと非同期タスクの両方を使用できます。
<button @onclick="Increment">+</button>
<button @onclick="DecrementAsync">-</button>
<button @onclick="() => _count = 0">Reset</button>
<p>Count: @_count</p>
@code {
private int _count = 0;
private void Increment() => _count++;
private async Task DecrementAsync()
{
await Task.Delay(200); // simulate async work
_count--;
}
}イベント引数
DOM イベントはイベント引数オブジェクトを提供します。ハンドラーで適切な引数型を宣言すると、座標、キーコード、入力値などにアクセスできます。
<input @onkeydown="OnKeyDown" @onfocus="OnFocus" />
<div @onmousemove="OnMouseMove">Move here</div>
<p>@_info</p>
@code {
private string _info = "";
private void OnKeyDown(KeyboardEventArgs e)
=> _info = $"Key: {e.Key} (Ctrl={e.CtrlKey})";
private void OnFocus(FocusEventArgs e)
=> _info = "Input focused";
private void OnMouseMove(MouseEventArgs e)
=> _info = $"Mouse: ({e.ClientX}, {e.ClientY})";
}親子間通信のための EventCallback
EventCallback は、Blazor で子から親へ通信するための仕組みです。通常の Action/Func とは異なり、親で StateHasChanged を自動的に呼び出し、例外も適切に処理します。
@* Child: ProductCard.razor *@
<button @onclick="() => OnBuy.InvokeAsync(Product)">Buy</button>
@code {
[Parameter] public Product Product { get; set; } = default!;
[Parameter] public EventCallback<Product> OnBuy { get; set; }
}
@* Parent: *@
<ProductCard Product="p" OnBuy="HandleBuy" />
@code {
private async Task HandleBuy(Product p)
{
await CartService.AddAsync(p);
// Parent re-renders automatically
}
}デフォルト動作の防止と伝播の停止
@onclick:preventDefault を使うとブラウザーのデフォルト動作をキャンセルでき、@onclick:stopPropagation を使うとイベントのバブリングを停止できます。
@* Prevent form submission *@
<form @onsubmit="HandleSubmit" @onsubmit:preventDefault>
<input @bind="_value" />
<button type="submit">Save</button>
</form>
@* Stop click from bubbling to parent div *@
<div @onclick="ParentClicked">
<button @onclick="ChildClicked"
@onclick:stopPropagation>
Click me
</button>
</div>カスタムコンポーネントでの @bind-Value による双方向バインディング
カスタムコンポーネントに Value/ValueChanged パターンを実装すると、親から @bind-Value を使用できるようになります。これは Blazor 標準の双方向バインディング契約です。
@* RatingInput.razor *@
@for (int i = 1; i <= 5; i++)
{
int star = i;
<span class="@(star <= Value ? "filled" : "")"
@onclick="() => ValueChanged.InvokeAsync(star)">★</span>
}
@code {
[Parameter] public int Value { get; set; }
[Parameter] public EventCallback<int> ValueChanged { get; set; }
}
@* Usage: *@
<RatingInput @bind-Value="_rating" />入力イベントのデバウンス
ユーザー入力によって高コストな処理(API 呼び出しや重いフィルタリング)が実行される場合は、CancellationTokenSource を使ってイベントをデバウンスし、ユーザーが入力を停止してから実行するようにします。
@code {
private string _query = "";
private CancellationTokenSource? _cts;
private async Task OnSearchInput(ChangeEventArgs e)
{
_query = e.Value?.ToString() ?? "";
_cts?.Cancel();
_cts = new CancellationTokenSource();
try
{
await Task.Delay(300, _cts.Token); // wait 300ms
Results = await SearchService.SearchAsync(_query);
}
catch (TaskCanceledException) { /* user still typing */ }
}
private List<string> Results = new();
}確認問題
Blazor で子から親へイベントを渡す場合、Action/Func より EventCallback を使う利点は何ですか?
まとめ:データバインディングとイベント処理
主なポイント:
- 一方向バインディング:
@exprで C# 式を出力します - 双方向バインディング:入力に
@bindを使用し、@bind:eventでトリガーを変更します - DOM イベント:
@onclick、@oninput、@onkeydownと型付きイベント引数を使用します EventCallback<T>:StateHasChanged を自動的に呼び出す、子から親への通信です- カスタムコンポーネントの双方向バインディングには Value/ValueChanged を実装します
- 高コストな処理をデバウンスして、不要な API 呼び出しを減らします
よくある質問
「データバインディングとイベント処理」レッスンは無料ですか?
はい。「データバインディングとイベント処理」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C# Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C# Academyコースには全4レッスンが含まれています。
「データバインディングとイベント処理」で何を学びますか?
一方向および双方向のデータバインディングを適用し、DOMとコンポーネントのイベントを処理して、EventCallbackを使います。 ブラウザで直接実行するハンズオンコードでC# Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
C# Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのC# Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「データバインディングとイベント処理」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このC# Academyレッスンでコードを書いて実行できますか?
はい。すべてのC# Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- Blazorコンポーネントモデル
- データバインディングとイベント処理
- コンポーネント間通信とDI
- Blazorの状態管理