0Pricing
C# Academy · レッスン

データバインディングとイベント処理

一方向および双方向のデータバインディングを適用し、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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Blazorコンポーネントモデル
  2. データバインディングとイベント処理
  3. コンポーネント間通信とDI
  4. Blazorの状態管理
← C# Academyに戻る