VieTopik
Tiếng HànTiếng AnhIT
  • Góc học tập
Tải app
  • Thư viện
  • Luyện thi
  • Cẩm nang
  • Góc học tập
WinForms với OracleNền tảng WinForms
Bài 3/15
5 phút

Sự kiện

Nội dung bài · 6 mục
  1. 1.Khái niệm
  2. 2.Ví dụ
  3. 3.Handler viết bằng lambda
  4. 4.Thử ngay
  5. 5.Lỗi hay gặp
  6. 6.Tóm tắt

Nút "Lưu" đã hiện nhưng bấm vào không có gì xảy ra. App console chạy từ trên xuống rồi dừng, còn app có cửa sổ thì chờ người dùng bấm, gõ, chọn. Bài này cho code chạy đúng vào những lúc đó.

Khái niệm

🔔 Event (sự kiện): thông báo mà một object phát ra khi có chuyện xảy ra, ví dụ Click của nút khi được bấm.

🎧 Event handler: method được gắn vào event bằng +=, chạy mỗi lần event đó xảy ra.

Cách chạy này giống controller ở khoá ASP.NET Core: action không tự chạy, nó chờ request tới. Handler cũng chờ, nhưng chờ cú bấm của người dùng.

Ví dụ

class MainForm : Form
{
    private int _count = 0;
    private readonly Label _countLabel = new Label
    {
        Text = "Giỏ hàng: 0",
        AutoSize = true
    };

    public MainForm()
    {
        Text = "Giỏ hàng";

        var panel = new FlowLayoutPanel
        {
            Dock = DockStyle.Fill,
            FlowDirection = FlowDirection.TopDown,
            Padding = new Padding(12)
        };
        var addButton = new Button { Text = "Thêm" };
        addButton.Click += AddButton_Click;

        panel.Controls.Add(addButton);
        panel.Controls.Add(_countLabel);
        Controls.Add(panel);
    }

    private void AddButton_Click(
        object? sender, EventArgs e)
    {
        _count = _count + 1;
        _countLabel.Text = $"Giỏ hàng: {_count}";
    }
}
  • addButton.Click += AddButton_Click; gắn method vào event. Không có dấu () sau tên method: ta giao method cho nút giữ để gọi sau, không gọi ngay.
  • Handler của Click luôn nhận hai tham số: sender là object phát ra event (ở đây là nút), e chứa thông tin thêm. sender có kiểu object?: object là kiểu chung mà class nào cũng kế thừa, nên giữ được mọi object.
  • _countLabel là field, vì cả constructor lẫn handler đều cần dùng nó. Biến addButton chỉ dùng trong constructor nên để là biến cục bộ (biến khai báo trong method hay constructor).

Handler viết bằng lambda

Handler ngắn có thể viết thẳng bằng lambda, như bài Lambda của khoá C# Core:

// Trong constructor, thay dòng gắn handler cũ
addButton.Click += (sender, e) =>
{
    _count = _count + 1;
    _countLabel.Text = $"Giỏ hàng: {_count}";
};

Hai tham số sender, e đặt trong ngoặc ( ), thân nhiều lệnh đặt trong { }. Handler dài thì nên viết thành method riêng có tên cho dễ đọc.

Thử ngay

Dùng lại bản có method AddButton_Click. Trong constructor, chép thêm một lần dòng gắn handler, để có hai dòng giống hệt:

addButton.Click += AddButton_Click;
addButton.Click += AddButton_Click;

Đoán trước khi chạy: bấm "Thêm" một lần thì nhãn hiện Giỏ hàng: 1 hay Giỏ hàng: 2?

Xem kết quả
Giỏ hàng: 2

Mỗi += gắn thêm một lần. Event giữ một danh sách handler và gọi lần lượt từng cái, nên cùng một method được gọi hai lần cho một cú bấm.

Lỗi hay gặp

Dùng = thay cho +=. Event chỉ cho gắn thêm hoặc gỡ ra, không cho gán đè.

// SAI — lỗi compile: event chỉ đứng trước += hoặc -=
var addButton = new Button { Text = "Thêm" };
addButton.Click = (sender, e) => { };
// ĐÚNG
var addButton = new Button { Text = "Thêm" };
addButton.Click += (sender, e) => { };

Gắn handler trong chính handler. Mỗi lần bấm lại += thêm một lần, lần bấm sau chạy gấp đôi. Gắn handler một lần duy nhất, trong constructor.

Tóm tắt

  • Event là thông báo object phát ra, như Click của nút.
  • Gắn handler bằng +=, không có () sau tên method.
  • Handler nhận sender và e. Viết bằng method hoặc lambda đều được.
  • Mỗi += gắn thêm một lần, nên gắn handler một lần trong constructor.

Tự kiểm tra

0/3 câu
Câu 1

Dòng nào gắn method SaveButton_Click vào nút saveButton đúng cách?

Câu 2

Handler cần đổi chữ trên một Label. Vì sao Label đó thường là field chứ không phải biến trong constructor?

Câu 3

Hai nút cùng gắn một handler. Trong handler, làm sao biết nút nào vừa được bấm?

Control và layoutKiểm tra dữ liệu nhập

Nội dung bài

  1. 1.Khái niệm
  2. 2.Ví dụ
  3. 3.Handler viết bằng lambda
  4. 4.Thử ngay
  5. 5.Lỗi hay gặp
  6. 6.Tóm tắt