Làm cách nào tôi có thể tạo sự kiện của riêng mình trong C #?


122

Làm cách nào tôi có thể tạo sự kiện của riêng mình trong C #?

Câu trả lời:


217

Đây là một ví dụ về việc tạo và sử dụng một sự kiện với C #

using System;

namespace Event_Example
{
    //First we have to define a delegate that acts as a signature for the
    //function that is ultimately called when the event is triggered.
    //You will notice that the second parameter is of MyEventArgs type.
    //This object will contain information about the triggered event.
    public delegate void MyEventHandler(object source, MyEventArgs e);

    //This is a class which describes the event to the class that recieves it.
    //An EventArgs class must always derive from System.EventArgs.
    public class MyEventArgs : EventArgs
    {
        private string EventInfo;
        public MyEventArgs(string Text)
        {
            EventInfo = Text;
        }
        public string GetInfo()
        {
            return EventInfo;
        }
    }

    //This next class is the one which contains an event and triggers it
    //once an action is performed. For example, lets trigger this event
    //once a variable is incremented over a particular value. Notice the
    //event uses the MyEventHandler delegate to create a signature
    //for the called function.
    public class MyClass
    {
        public event MyEventHandler OnMaximum;
        private int i;
        private int Maximum = 10;
        public int MyValue
        {
            get
            {
                return i;
            }
            set
            {
                if(value <= Maximum)
                {
                    i = value;
                }
                else
                {
                    //To make sure we only trigger the event if a handler is present
                    //we check the event to make sure it's not null.
                    if(OnMaximum != null)
                    {
                        OnMaximum(this, new MyEventArgs("You've entered " +
                            value.ToString() +
                            ", but the maximum is " +
                            Maximum.ToString()));
                    }
                }
            }
        }
    }

    class Program
    {
        //This is the actual method that will be assigned to the event handler
        //within the above class. This is where we perform an action once the
        //event has been triggered.
        static void MaximumReached(object source, MyEventArgs e)
        {
            Console.WriteLine(e.GetInfo());
        }

        static void Main(string[] args)
        {
            //Now lets test the event contained in the above class.
            MyClass MyObject = new MyClass();
            MyObject.OnMaximum += new MyEventHandler(MaximumReached);

            for(int x = 0; x <= 15; x++)
            {
                MyObject.MyValue = x;
            }

            Console.ReadLine();
        }
    }
}

4
Sau khi truy cập hàng trăm lời giải thích, điều này cuối cùng đã giúp tôi hiểu. SE đã đúng, bài viết vẫn có liên quan sau vài năm.

1
{Meh!} Tôi luôn quên viết vào eventphần cho lớp.
jp2code

51

Tôi có một cuộc thảo luận đầy đủ về các sự kiện và đại biểu trong bài viết sự kiện của tôi . Đối với loại sự kiện đơn giản nhất, bạn chỉ cần khai báo một sự kiện công khai và trình biên dịch sẽ tạo cả sự kiện và trường để theo dõi người đăng ký:

public event EventHandler Foo;

Nếu bạn cần logic đăng ký / hủy đăng ký phức tạp hơn, bạn có thể thực hiện điều đó một cách rõ ràng:

public event EventHandler Foo
{
    add
    {
        // Subscription logic here
    }
    remove
    {
        // Unsubscription logic here
    }
}

1
Tôi không chắc chắn làm thế nào để gọi sự kiện từ mã của tôi, nhưng hóa ra nó thực sự rõ ràng. Bạn chỉ cần gọi nó như một phương thức truyền cho nó một đối tượng người gửi và EventArss. [I E. if (fooHappened) Foo (người gửi, eventArss); ]
Richard Garside

2
@Richard: Không hoàn toàn; bạn cần xử lý trường hợp không có người đăng ký, vì vậy tham chiếu của đại biểu sẽ là null.
Jon Skeet

Mong được cập nhật C # 4 về các sự kiện an toàn của chủ đề trong bài viết mà bạn đã liên kết. Công việc thực sự tuyệt vời, @JonSkeet!
kdbanman

20

Bạn có thể khai báo một sự kiện với mã sau đây:

public event EventHandler MyOwnEvent;

Một loại đại biểu tùy chỉnh thay vì EventHandler có thể được sử dụng nếu cần.

Bạn có thể tìm thấy thông tin chi tiết / hướng dẫn về việc sử dụng các sự kiện trong .NET trong bài viết Hướng dẫn sự kiện (MSDN).


4

để làm điều đó chúng ta phải biết ba thành phần

  1. nơi chịu trách nhiệm firing the Event
  2. nơi chịu trách nhiệm responding to the Event
  3. sự kiện chính nó

    a. Biến cố

    b .EventArss

    c. Bảng liệt kê sự kiện

bây giờ hãy tạo sự kiện kích hoạt khi hàm được gọi

nhưng tôi có thứ tự giải quyết vấn đề này như thế này: Tôi đang sử dụng lớp trước khi tôi tạo nó

  1. nơi chịu trách nhiệm responding to the Event

    NetLog.OnMessageFired += delegate(object o, MessageEventArgs args) 
    {
            // when the Event Happened I want to Update the UI
            // this is WPF Window (WPF Project)  
            this.Dispatcher.Invoke(() =>
            {
                LabelFileName.Content = args.ItemUri;
                LabelOperation.Content = args.Operation;
                LabelStatus.Content = args.Status;
            });
    };

NetLog là một lớp tĩnh tôi sẽ giải thích nó sau

bước tiếp theo là

  1. nơi chịu trách nhiệm firing the Event

    //this is the sender object, MessageEventArgs Is a class I want to create it  and Operation and Status are Event enums
    NetLog.FireMessage(this, new MessageEventArgs("File1.txt", Operation.Download, Status.Started));
    downloadFile = service.DownloadFile(item.Uri);
    NetLog.FireMessage(this, new MessageEventArgs("File1.txt", Operation.Download, Status.Finished));

bước thứ ba

  1. sự kiện chính nó

Tôi đã làm cong sự kiện trong một lớp có tên NetLog

public sealed class NetLog
{
    public delegate void MessageEventHandler(object sender, MessageEventArgs args);

    public static event MessageEventHandler OnMessageFired;
    public static void FireMessage(Object obj,MessageEventArgs eventArgs)
    {
        if (OnMessageFired != null)
        {
            OnMessageFired(obj, eventArgs);
        }
    }
}

public class MessageEventArgs : EventArgs
{
    public string ItemUri { get; private set; }
    public Operation Operation { get; private set; }
    public Status Status { get; private set; }

    public MessageEventArgs(string itemUri, Operation operation, Status status)
    {
        ItemUri = itemUri;
        Operation = operation;
        Status = status;
    }
}

public enum Operation
{
    Upload,Download
}

public enum Status
{
    Started,Finished
}

lớp này ngay bây giờ chứa the Event, EventArgsEventArgs Enumsthe functionchịu trách nhiệm về bắn sự kiện

xin lỗi vì câu trả lời dài này


Sự khác biệt chính của câu trả lời này là làm cho sự kiện tĩnh, cho phép nhận các sự kiện mà không yêu cầu tham chiếu đến đối tượng đã kích hoạt sự kiện. Tuyệt vời để đăng ký các sự kiện từ nhiều điều khiển độc lập.
Radderz
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.