ฉันจะสร้างเหตุการณ์ของตัวเองใน C # ได้อย่างไร?


คำตอบ:


217

นี่คือตัวอย่างของการสร้างและใช้งานเหตุการณ์ด้วย 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
หลังจากเยี่ยมชมคำอธิบายเป็นร้อยครั้งในที่สุดสิ่งนี้ก็ช่วยให้ฉันเข้าใจ SE เป็นสิทธิที่โพสต์เป็นยังมีความเกี่ยวข้องหลังจากหลายปี

1
{Meh!} ฉันมักจะลืมเขียนในeventส่วนของชั้นเรียน
jp2code

51

ฉันมีการสนทนาแบบเต็มของเหตุการณ์และผู้ได้รับมอบหมายในของฉันบทความเหตุการณ์ สำหรับเหตุการณ์ที่ง่ายที่สุดคุณสามารถประกาศกิจกรรมสาธารณะจากนั้นคอมไพเลอร์จะสร้างทั้งเหตุการณ์และฟิลด์เพื่อติดตามสมาชิก:

public event EventHandler Foo;

หากคุณต้องการตรรกะการสมัคร / ยกเลิกการสมัครที่ซับซ้อนมากขึ้นคุณสามารถทำได้อย่างชัดเจน:

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

1
ฉันไม่แน่ใจว่าจะเรียกเหตุการณ์จากรหัสของฉันอย่างไร แต่ปรากฎว่าชัดเจนจริงๆ คุณเรียกมันว่าเป็นวิธีการส่งผ่านผู้ส่งและวัตถุ EventArgs [คือ ถ้า (fooHappened) Foo (ผู้ส่ง eventArgs); ]
Richard Garside

2
@ ริชาร์ด: ไม่ค่อย; คุณต้องจัดการกรณีที่ไม่มีสมาชิกดังนั้นการอ้างอิงของผู้รับมอบสิทธิ์จะเป็นโมฆะ
Jon Skeet

รอคอยการอัปเดต C # 4 เกี่ยวกับเหตุการณ์ที่ปลอดภัยของเธรดในบทความที่คุณเชื่อมโยง เยี่ยมจริงๆ @JonSkeet!
kdbanman

20

คุณสามารถประกาศกิจกรรมด้วยรหัสต่อไปนี้:

public event EventHandler MyOwnEvent;

สามารถใช้ประเภทผู้รับมอบสิทธิ์แบบกำหนดเองแทน EventHandler ได้หากจำเป็น

คุณสามารถดูข้อมูลโดยละเอียด / บทช่วยสอนเกี่ยวกับการใช้เหตุการณ์ใน. NET ได้ในบทความการสอนเหตุการณ์ (MSDN)


4

เราต้องรู้ส่วนประกอบทั้งสาม

  1. สถานที่รับผิดชอบ firing the Event
  2. สถานที่รับผิดชอบ responding to the Event
  3. เหตุการณ์นั้นเอง

    เหตุการณ์

    ข. EventArgs

    ค. การแจงนับ EventArgs

ตอนนี้ให้สร้างเหตุการณ์ที่เริ่มทำงานเมื่อมีการเรียกใช้ฟังก์ชัน

แต่ลำดับการแก้ปัญหาของฉันเป็นแบบนี้ฉันใช้คลาสก่อนที่จะสร้าง

  1. สถานที่รับผิดชอบ 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 เป็นคลาสคงที่ฉันจะอธิบายในภายหลัง

ขั้นตอนต่อไปคือ

  1. สถานที่รับผิดชอบ 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));

ขั้นตอนที่สาม

  1. เหตุการณ์นั้นเอง

ฉันวิปริตเหตุการณ์ภายในคลาสชื่อ 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
}

ระดับนี้ในขณะนี้มีthe Event, EventArgsและEventArgs Enumsและthe functionความรับผิดชอบในการยิงเหตุการณ์

ขออภัยสำหรับคำตอบที่ยาวนี้


ความแตกต่างที่สำคัญในคำตอบนี้คือการทำให้เหตุการณ์คงที่ซึ่งทำให้สามารถรับเหตุการณ์ได้โดยไม่ต้องอ้างอิงถึงวัตถุที่ทำให้เหตุการณ์เกิดขึ้น เหมาะสำหรับการสมัครเข้าร่วมกิจกรรมจากการควบคุมอิสระหลายรายการ
Radderz
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.