C #에서 나만의 이벤트를 만들려면 어떻게해야합니까?


122

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 개체를 전달하는 메서드처럼 호출하면됩니다. [즉. if (fooHappened) Foo (sender, eventArgs); ]
Richard Garside 2012 년

2
@Richard : 정답이 아닙니다. 구독자가없는 경우를 처리해야하므로 델리게이트 참조는 null이됩니다.
Jon Skeet

링크 한 기사에서 스레드 안전 이벤트에 대한 C # 4 업데이트를 기대합니다. @JonSkeet 정말 대단합니다!
kdbanman

20

다음 코드를 사용하여 이벤트를 선언 할 수 있습니다.

public event EventHandler MyOwnEvent;

필요한 경우 EventHandler 대신 사용자 지정 대리자 형식을 사용할 수 있습니다.

이벤트 자습서 (MSDN) 문서에서 .NET의 이벤트 사용에 대한 자세한 정보 / 튜토리얼을 찾을 수 있습니다 .


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, EventArgsEventArgs Enumsthe function이벤트를 발사에 대한 책임

이 긴 대답에 대해 죄송합니다


이 답변의 주요 차이점은 이벤트를 정적으로 만들어 이벤트를 발생시킨 객체에 대한 참조없이 이벤트를 수신 할 수 있도록하는 것입니다. 여러 독립 컨트롤에서 이벤트를 구독하는 데 적합합니다.
Radderz
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.