0Pricing
C# Academy · Урок

Привязка данных и обработка событий

Применяйте одностороннюю и двустороннюю привязку данных, обрабатывайте события DOM и компонентов и используйте EventCallback.

«Привязка данных и обработка событий» — бесплатный урок C# Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C# Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C# Academy содержит 4 уроков всего.

Привязка в Blazor

Blazor поддерживает три направления привязки: одностороннюю (только чтение, @expr), событийную (@onclick и другие) и двустороннюю (@bind). Вместе они образуют основу реактивных пользовательских интерфейсов.

Односторонняя привязка данных

Просто выведите выражение 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. В отличие от обычного делегата, он автоматически вызывает 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();
}

Быстрая проверка

В чём преимущество EventCallback перед обычным делегатом для передачи событий от дочернего компонента родительскому в Blazor?

Итоги: привязка данных и обработка событий

Главные выводы:

  • Односторонняя привязка: выводите выражения C# с помощью @expr
  • Двусторонняя привязка: используйте @bind для элементов ввода; @bind:event изменяет событие-триггер
  • События DOM: @onclick, @oninput, @onkeydown с типизированными аргументами событий
  • EventCallback<T>: взаимодействие дочернего компонента с родительским с автоматическим вызовом StateHasChanged
  • Реализуйте Value/ValueChanged для двусторонней привязки пользовательского компонента
  • Откладывайте ресурсоёмкие операции, чтобы сократить количество ненужных вызовов API

Часто задаваемые вопросы

Урок «Привязка данных и обработка событий» бесплатный?

Да — полный текст урока «Привязка данных и обработка событий» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C# Academy, подпишись на CoddyKit PRO. Курс C# Academy содержит 4 уроков всего.

Чему я научусь в уроке «Привязка данных и обработка событий»?

Применяйте одностороннюю и двустороннюю привязку данных, обрабатывайте события DOM и компонентов и используйте EventCallback. Ты практикуешь C# Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C# Academy?

Предыдущий опыт не требуется. C# Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «Привязка данных и обработка событий»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C# Academy?

Да. Каждый урок C# Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Модель компонентов Blazor
  2. Привязка данных и обработка событий
  3. Взаимодействие компонентов и DI
  4. Управление состоянием в Blazor
← Назад к C# Academy