C # 'da kendi olayımı nasıl yapabilirim?


Yanıtlar:


217

İşte C # ile bir olay oluşturma ve kullanma örneği

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
Yüzlerce açıklamayı ziyaret ettikten sonra, bu nihayet anlamama yardımcı oldu. SE mesajlar, haklıydı olan birkaç yıl sonra hala alakalı.

1
{Meh!} Her zaman sınıf için bir kısmını yazmayı unuturumevent .
jp2code

51

Etkinlikler makalemde olaylar ve delegelerle ilgili tam bir tartışmam var . En basit olay türü için, sadece bir genel olay ilan edebilirsiniz ve derleyici, aboneleri takip etmek için hem bir olay hem de bir alan yaratacaktır:

public event EventHandler Foo;

Daha karmaşık abonelik / abonelikten çıkma mantığına ihtiyacınız varsa, bunu açıkça yapabilirsiniz:

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

1
Etkinliği kodumdan nasıl çağıracağımdan emin değildim, ancak gerçekten açık olduğu ortaya çıktı. Onu bir gönderen ve EventArgs nesnesini geçiren bir yöntem gibi çağırırsınız. [yani. if (fooHappened) Foo (gönderen, eventArgs); ]
Richard Garside

2
@Richard: Pek sayılmaz; hiçbir abonenin olmadığı durumu halletmeniz gerekir, böylece temsilci referansı boş olacaktır.
Jon Skeet

Bağlandığınız makalede iş parçacığı güvenli olaylarla ilgili C # 4 güncellemesini dört gözle bekliyorum. Gerçekten harika bir iş çıkardınız @JonSkeet!
kdbanman

20

Aşağıdaki kodla bir olay ilan edebilirsiniz:

public event EventHandler MyOwnEvent;

Gerekirse EventHandler yerine özel bir temsilci türü kullanılabilir.

Etkinlik Öğreticisi (MSDN) makalesinde .NET'teki olayların kullanımına ilişkin ayrıntılı bilgileri / öğreticileri bulabilirsiniz .


4

bunu yapmak için üç bileşeni bilmeliyiz

  1. sorumlu yer firing the Event
  2. sorumlu yer responding to the Event
  3. Etkinliğin kendisi

    a. Etkinlik

    b .EventArgs

    c. EventArgs numaralandırması

şimdi bir işlev çağrıldığında tetiklenen Etkinlik oluşturalım

ama bu sorunu şu şekilde çözme emrim: Sınıfı oluşturmadan önce kullanıyorum

  1. sorumlu yer 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, daha sonra açıklayacağım statik bir sınıftır

sonraki adım

  1. sorumlu yer 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));

üçüncü adım

  1. Etkinliğin kendisi

Olayı NetLog adlı bir sınıf içinde çarpıttım

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
}

Bu sınıf artık içerirler the Event, EventArgsveEventArgs Enums ve the functionolay ateş sorumlu

bu uzun cevap için özür dilerim


Bu yanıttaki temel fark, olayı tetikleyen nesneye bir referans gerekmeden olayların alınmasına izin veren olayı statik hale getirmektir. Birden çok bağımsız kontrolden etkinliklere abone olmak için harika.
Radderz
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.