【问题标题】:How can I make my own event in C#?如何在 C# 中创建自己的事件?
【发布时间】:2010-10-12 00:40:08
【问题描述】:

如何在 C# 中创建自己的事件?

【问题讨论】:

    标签: c# .net events


    【解决方案1】:

    要做到这一点,我们必须知道三个组件

    1. 负责firing the Event的地方
    2. 负责responding to the Event的地方
    3. 事件本身

      一个。事件

      b .EventArgs

      c。 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 EventEventArgsEventArgs Enumsthe function

    抱歉这么长的回答

    【讨论】:

    • 他们在这个答案中的主要区别在于使事件静态化,这允许在不需要引用触发事件的对象的情况下接收事件。非常适合订阅来自多个独立控件的事件。
    【解决方案2】:

    这是一个使用 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();
            }
        }
    }
    

    【讨论】:

    • 看了一百个解释,终于明白了。 SE 是对的,帖子仍然几年后仍然相关。
    • {Meh!} 我总是忘记在课程的event 部分写字。
    【解决方案3】:

    您可以使用以下代码声明事件:

    public event EventHandler MyOwnEvent;
    

    如果需要,可以使用自定义委托类型而不是 EventHandler。

    您可以在文章 Events Tutorial (MSDN) 中找到有关在 .NET 中使用事件的详细信息/教程。

    【讨论】:

      【解决方案4】:

      我的events article 对活动和代表进行了全面讨论。对于最简单的事件,您只需声明一个公共事件,编译器就会创建一个事件和一个字段来跟踪订阅者:

      public event EventHandler Foo;
      

      如果您需要更复杂的订阅/取消订阅逻辑,您可以明确地这样做:

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

      【讨论】:

      • 我不确定如何从我的代码中调用该事件,但事实证明它非常明显。您只需将其称为传递发送者和 EventArgs 对象的方法即可。 [IE。 if (fooHappened) Foo(sender, eventArgs); ]
      • @Richard:不完全;您需要处理没有订阅者的情况,因此委托引用将为空。
      • 期待您链接的文章中有关线程安全事件的 C# 4 更新。真的很棒,@JonSkeet!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-20
      • 2021-10-11
      • 2012-05-07
      • 1970-01-01
      • 2011-10-29
      • 2013-11-29
      相关资源
      最近更新 更多