Как сделать собственное мероприятие на 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); ]
Ричард Гарсайд,

2
@ Ричард: Не совсем; вам нужно обработать случай, когда нет подписчиков, поэтому ссылка на делегат будет нулевой.
Джон Скит,

С нетерпением жду обновления C # 4 о потокобезопасных событиях в статье, которую вы связали. Действительно отличная работа, @JonSkeet!
kdbanman

20

Вы можете объявить событие с помощью следующего кода:

public event EventHandler MyOwnEvent;

При необходимости можно использовать настраиваемый тип делегата вместо EventHandler.

Вы можете найти подробную информацию / руководства по использованию событий в .NET в статье Events Tutorial (MSDN).


4

для этого мы должны знать три компонента

  1. место, ответственное за firing the Event
  2. место, ответственное за responding to the Event
  3. само событие

    а. Мероприятие

    b .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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.