STDIO
Tìm kiếm gần đây

    Nội dung

    Event Trong C#

    25/10/2015
    30/04/2017
    Event Trong C#
    Thông thường khi mới bắt đầu lập trình giao diện Windows From Application, Windows Phone, chúng ta thường xuyên tiếp xúc với những sự kiện như Click của Button, TextChanged của Textblock. Vậy những sự kiện đó được xây dựng như thế này thì trong bài viết này sẽ làm rõ cũng như cách viết ra những sự kiện như vậy để giúp bạn đọc có thể hiểu rõ sâu hơn về sự kiện trong C#.

    Giới thiệu

    Thông thường khi mới bắt đầu lập trình giao diện Windows From Application, Windows Phone, chúng ta thường xuyên tiếp xúc với những sự kiện như Click của Button, TextChanged của Textblock. Những phương thức xử lý sự kiện tương ứng như:

    void btnSubmit_Clicked(object sender, System.EventArgs e)

    void txtContent_TextChanged(object sender, RoutedEventArgs e)

    Vậy những sự kiện đó được xây dựng như thế nào, những đối số sender, e  ở hai phương thức trên có ý nghĩa như thế nào thì trong bài viết này sẽ làm rõ cũng như cách viết ra những sự kiện như vậy để giúp bạn đọc có thể hiểu rõ sâu hơn về sự kiện trong C#.

    Tiền đề bài viết

    Lúc mới bắt đầu lập trình C#, tôi nhận thấy không phải ai cũng có thể hiểu được khái niệm event, cũng như cách tạo ra nó như thế nào. Sau một quá trình học tìm hiểu, học tập tôi muốn chia sẽ kiến thức khá bổ ích này cùng các độc giả.

    Đối tượng hướng đến

    Những lập trình viên C#, gặp khó khăn khi tiếp cận với khái niệm event trong ngôn ngữ lập trình C#.

    Các bạn nên xem qua bài viết Delegates và Events trong C# của tác giả Hiếu Nguyễn để có tiếp cận bài viết này một cách dễ dàng.

    Khai báo sự kiện

    Trong bài viết này tôi sẽ lấy ví dụ là 1 sản phẩm (Product) có trường dữ liệu là giá của sản phẩm (Price). Khi mà trường dữ liệu này thay đổi thì sẽ phát sinh sự kiện và có các thông tin gửi kèm theo sự kiện là giá cũ và giá mới (OldPrice) và giá mới (NewPrice).

    Để khai báo một sự kiện trước tiên ta tạo một delegate.

    void delegate PriceChangedHandler(decimal oldPrice, decimal newPrice)

    Khai báo sự kiện

    public  delegate void PriceChangedHandler(decimal oldPrice, decimal newPrice);
    public class Product
    {
       public event PriceChangedHandler PriceChanged;  
    }
    

    Triển khai sự kiện

    Phần trên chúng ta đã khai báo sự kiện PriceChanged. Bây giờ ta sẽ đi tiếp phần tiếp theo là triển khai sự kiện này để khi giá (Price) thay đổi thì sẽ phát sinh sự kiện;

    Khai báo trường dữ liệu của class Product:

    private decimal _price;

    và triển khai sự kiện sử dụng get set

    public class Product
    {
        private decimal _price;
        public event PriceChangedHandler PriceChanged;  
        public decimal Price
        {
            get
            {
                return this._price;
            }
            set
            {
                if (_price == value)
                    return;
                decimal oldPrice = _price;
                _price = value;
                if (PriceChanged != null)
                    PriceChanged(oldPrice, _price);
            }
        }     
    }

    Triển khai hàm Main:

    class Program
        {
            static void Main(string[] args)
            {
                Product product = new Product();
                product.Price = 10000;
                product.PriceChanged += product_PriceChanged;
                product.Price = 50000;
                Console.ReadLine();
            }
    
            static void product_PriceChanged(decimal oldPrice, decimal newPrice)
            {
                Console.WriteLine("Old Price: {0}", oldPrice);
                Console.WriteLine("New Price: {0}", newPrice);
            }
        }
    

    Trong mô hình sự kiện có hai khai niệm các bạn cần quan tâm là đối tượng phát sinh sự kiện (Broadcaster), và phương thức xử lý sự kiện (Subscriber).

    • Broadcaster: Là kiểu chứa event, ở trên là Product. Hoặc có thể là Button, Textblock, Combobox.
    • Subscriber: Là phương thức đăng kí và xử lý sự kiện do những đối tượng ở Broadcaster phát sinh.

    Mô hình chuẩn sự kiện trong .Net

    Nhiều khi chúng ta cần phải tạo ra nhiều sự kiện, mỗi sự kiện có cách viết khác nhau, không đồng bộ. Để khắc phục nhược điểm đó thì .Net Framework có đưa là một mô hình chuẩn để viết sự kiện giúp cho việc viết sự kiện dễ dàng. Mô hình này như sau:

    Khai báo delegate có quy tắc rằng buộc:

    • Delegate có kiểu trả về là kiểu void.
    • Delegate có hai tham số, tham số thứ nhất có kiểu là object, tham số thứ hai có kiểu EventArgs. object chính là đối tượng phát sinh sự kiện, EventArgs chính là class giữ thông tin mà đối tượng gửi kèm trong quá trình phát sinh sự kiện.

    Class PriceChangedEventArgs:

    public class PriceChangedEventArgs
    {
    	public readonly decimal OldPrice;
    	public readonly decimal NewPrice;
    	
    	public PriceChangedEventArgs(decimal oldPrice, decimal newPrice)
    	{
    		this.OldPrice = oldPrice;
    		this.NewPrice = newPrice;
    	}
    }

    Khai báo delegate

    public delegate void PriceChangedHandler(object sender, PriceChangedEventArgs e);

    Cuối cùng là tạo một phương thức virtual có phạm vi truy xuất là protect có nhiệm vụ phát sinh sự kiện:

    protected virtual void OnPriceChanged(PriceChangedEventArgs e)
    {
    	if (PriceChanged != null)
    		PriceChanged(this, e);
    }

    Triển khai sự kiện sử dụng get set

    public decimal Price
    {
    	get
    	{
    		return this._price;
    	}
    	set
    	{
    		if (_price == value)
    			return;
    		decimal oldPrice = _price;
    		_price = value;
    		OnPriceChanged(new PriceChangedEventArgs(oldPrice, _price));
    	}
    }
    

    Triển khai hàm main

    class Program
    {
    	static void Main(string[] args)
    	{
    		Product product = new Product();
    		product.Price = 10000;
    		product.PriceChanged += product_PriceChanged;
    		product.Price = 50000;
    		Console.ReadLine();
    	}
    
    	static void product_PriceChanged(object sender, PriceChangedEventArgs e)
    	{
    		Console.WriteLine("Old Price: {0}", e.OldPrice);
    		Console.WriteLine("New Price: {0}", e.NewPrice);
    	}
    }

    Các bạn để ý thấy phương thức xử lý sự kiện ở đây

    void product_PriceChanged(object sender, PriceChangedEventArgs e)

    Có điểm tương đồng với phương thức xử lý sự kiện click của Button hay TextChanged của TextBlock. Đến đây thì các bạn có thể hiểu được các tham số trong những phương thức này có ý nghĩa như thế nào.

    Ngoài ra chúng ta có thể ép kiểu sender về Product

    static void product_PriceChanged(object sender, PriceChangedEventArgs e)
    {
    	Product p = sender as Product;
    	Console.WriteLine("Price: {0}", p.Price);
    	Console.WriteLine("Old Price: {0}", e.OldPrice);
    	Console.WriteLine("New Price: {0}", e.NewPrice);
    }

    Lưu ý

    Với những quy tắc đặt ra như vậy, việc tuân thủ hay không là tùy theo mỗi lập trình viên, ví dụ tôi nhận thấy class Product của tôi không cần thiết phải viết thêm phương thức OnPriceChanged mà tôi có thể triển khai trực tiếp như sau:

    public decimal Price
    {
    	get
    	{
    		return this._price;
    	}
    	set
    	{
    		if (_price == value)
    			return;
    		decimal oldPrice = _price;
    		_price = value;
    		if (PriceChanged != null)
    			PriceChanged(this, new PriceChangedEventArgs(oldPrice, _price));
    	}
    }
    

    Download demo

    Demo_Event_VS2013.zip

    Thảo luận

    In order to comment you must be a STDIO Insider. Please sign up or log in to continue.

    Đăng nhập

    Bài viết liên quan

    Interface Trong C#

    Interface Trong C#

    Giới thiệu về interface trong C#, ý nghĩa sử dụng, tính ứng dụng và cách thức sử dụng interface trong C#.

    Huỳnh Minh Tân

    03/10/2017

    Delegates và Events trong C#

    Delegates và Events trong C#

    Bài viết này sẽ phần nào giúp các bạn hiểu rõ về Event và Delegate.

    Hiếu Nguyễn

    28/11/2014

    Tư Duy Tối Ưu Hóa Trong Lập Trình Games - Phần 1: Codes Trong C/C++

    Tư Duy Tối Ưu Hóa Trong Lập Trình Games - Phần 1: Codes Trong C/C++

    Bài viết hướng tối ưu hóa trong lập trình với C++, tối ưu hóa lập trình C++ với games, bài viết hướng games bởi vì games đòi hỏi hiệu năng rất cao, và các games lớn thông ...

    La Kiến Vinh

    18/09/2014

    template Trong C++

    template Trong C++

    Template là từ khóa trong C++, chúng ta có thể hiểu rằng là nó một kiểu dữ liệu trừu tượng, đặc trưng cho các kiểu dữ liệu cơ bản. Khi học về lập trình hướng đối tượng ...

    Trung Nguyễn

    21/09/2014

    Thao Tác Với Chuỗi Trong C/C++

    Thao Tác Với Chuỗi Trong C/C++

    Khái niệm chuỗi ký tự do con người đặt ra để thuận tiện trong việc sử dụng. Có thể hiểu đơn giản, chuỗi là tập hợp các ký tự được lưu trữ liên tiếp trong vùng nhớ máy ...

    Rye Nguyen

    28/07/2015

    Bản Chất Của Biến Trong C/C++

    Bản Chất Của Biến Trong C/C++

    Những ngày đầu được học và làm việc với các kiểu biến như int, float, char….Tôi luôn có những thắc mắc về:”Điều gì đang xảy ra bên trong biến int, char… khi ta cấp phát ...

    Trần Hữu Danh

    16/01/2015

    Type-casting Trong C++

    Type-casting Trong C++

    Chuyển đổi kiểu dữ liệu (type-casting) là một kỹ năng quan trọng trong lập trình C/C++. Một số bài toán phức tạp không thể giải được do dữ liệu không tương thích, qua quá ...

    Rye Nguyen

    30/07/2015

    9 Tính Năng Quan Trọng Trong C++11

    9 Tính Năng Quan Trọng Trong C++11

    C++11 là một phiên bản cải tiến và nâng cấp từ C++98 (hay các bạn vẫn gọi là C++), với những tính năng mới tối ưu hơn, dễ sử dụng hơn, dễ quản lý bộ nhớ hơn, và khắc phục ...

    Lê Minh Tài

    13/08/2015

    Đọc Ghi File Cơ Bản Trong C#

    Đọc Ghi File Cơ Bản Trong C#

    Hướng dẫn đọc và ghi file cơ bản sử dụng đối tượng File trong C#. Nhờ có các hàm hỗ trợ nên các thao tác đọc ghi dữ liệu trên file trong C# được thực hiện một cách nhanh ...

    Bùi Trung Hiếu

    07/04/2016

    Nhập Xuất Cơ Bản Trong C/C++

    Nhập Xuất Cơ Bản Trong C/C++

    Bài viết là tiền đề giúp cho người đọc làm quen trong việc kiểm soát dữ liệu nhập xuất cũng như các thao tác cơ bản trên C/C++.

    Nguyễn Hồng Sơn

    18/03/2016

    STDIO
    Trang chính
    Công ty TNHH STDIO

    30, Trịnh Đình Thảo, Hòa Thạnh, Tân Phú, Hồ Chí Minh
    +84 28.36205514 - +84 942.111912
    developer@stdio.vn

    383/1 Quang Trung, Phường 10, Quận Gò Vấp, Hồ Chí Minh
    Số giấy phép ĐKKD: 0311563559 do sở Kế hoạch và Đầu Tư TPHCM cấp ngày 23/02/2012

    ©STDIO, 2013 - 2020