【问题标题】:How to dispatch events in C#如何在 C# 中调度事件
【发布时间】:2010-03-15 15:55:23
【问题描述】:

我希望创建自己的事件并分派它们。 我以前从未在 C# 中这样做过,只是在 Flex 中。我想肯定有很多不同之处。

谁能给我一个很好的例子?

【问题讨论】:

  • WinForms、WebForms、ASP.NET MVC 还是 WPF?
  • 谢谢大家的回复!!他们一起帮助了我;)再次感谢!

标签: c# events event-dispatching


【解决方案1】:

在所有库类中都使用了一种模式。也推荐用于您自己的类,特别是对于框架/库代码。但是,当您偏离或跳过几步时,没有人会阻止您。

这是基于最简单的事件委托System.Eventhandler的示意图。

// The delegate type. This one is already defined in the library, in the System namespace
// the `void (object, EventArgs)` signature is also the recommended pattern
public delegate void Eventhandler(object sender, Eventargs args);  

// your publishing class
class Foo  
{
    public event EventHandler Changed;    // the Event

    protected virtual void OnChanged()    // the Trigger method, called to raise the event
    {
        // make a copy to be more thread-safe
        EventHandler handler = Changed;   

        if (handler != null)
        {
            // invoke the subscribed event-handler(s)
            handler(this, EventArgs.Empty);  
        }
    }

    // an example of raising the event
    void SomeMethod()
    {
       if (...)        // on some condition
         OnChanged();  // raise the event
    }
}

以及如何使用它:

// your subscribing class
class Bar
{       
    public Bar()
    {
        Foo f = new Foo();
        f.Changed += Foo_Changed;    // Subscribe, using the short notation
    }

    // the handler must conform to the signature
    void Foo_Changed(object sender, EventArgs args)  // the Handler (reacts)
    {
        // the things Bar has to do when Foo changes
    }
}

当你有信息要传递时:

class MyEventArgs : EventArgs    // guideline: derive from EventArgs
{
    public string Info { get; set; }
}

class Foo  
{
    public event EventHandler<MyEventArgs> Changed;    // the Event
    ...
    protected virtual void OnChanged(string info)      // the Trigger
    {
        EventHandler handler = Changed;   // make a copy to be more thread-safe
        if (handler != null)
        {
           var args = new MyEventArgs(){Info = info};  // this part will vary
           handler(this, args);  
        }
    }
}

class Bar
{       
   void Foo_Changed(object sender, MyEventArgs args)  // the Handler
   {
       string s = args.Info;
       ...
   }
}

更新

从 C# 6 开始,“触发器”方法中的调用代码变得更加容易,可以使用空条件运算符 ?. 缩短空测试,而无需复制,同时保持线程安全:

protected virtual void OnChanged(string info)   // the Trigger
{
    var args = new MyEventArgs{Info = info};    // this part will vary
    Changed?.Invoke(this, args);
}

【讨论】:

  • 我想我可以用我自己的类替换 EventArgs?
  • 是的,虽然你会使用 EventHandler ,其中 T 是你的事件参数的类型,又名.. public event EventHandler MyEvent;
  • 自定义 EventArgs 类从 EventArgs 继承也是一种常见的 .NET 实践
  • @Henk:这将是使用EventHandler&lt;T&gt;EventArgs 类的一个更好的例子。
  • @Janov:附加信息将作为参数传递给 OnChanged,然后在派生自 EventArgs 的类中。然后你可以使用 EventHandler 作为委托。
【解决方案2】:

C# 中的事件使用委托。

public static event EventHandler<EventArgs> myEvent;

static void Main()
{
   //add method to be called
   myEvent += Handler;

   //call all methods that have been added to the event
   myEvent(this, EventArgs.Empty);
}

static void Handler(object sender, EventArgs args)
{
  Console.WriteLine("Event Handled!");
}

【讨论】:

    【解决方案3】:

    使用典型的 .NET 事件模式,并假设您的事件中不需要任何特殊参数。您的典型事件和调度模式如下所示。

    public class MyClassWithEvents
        {
            public event EventHandler MyEvent;
    
            protected void OnMyEvent(object sender, EventArgs eventArgs)
            {
                if (MyEvent != null)
                {
                    MyEvent(sender, eventArgs);
                }
            }
    
            public void TriggerMyEvent()
            {
                OnMyEvent(sender, eventArgs);
            }
        }
    

    在事件中加入一些东西可以很简单:

    public class Program
    {
        public static void Main(string[] args)
        {
            MyClassWithEvents obj = new MyClassWithEvents();
    
            obj.MyEvent += obj_myEvent;
        }
    
        private static void obj_myEvent(object sender, EventArgs e)
        {
            //Code called when my event is dispatched.
        }
    }
    

    看看this MSDN page上的链接

    【讨论】:

      【解决方案4】:

      查看'delegates'.

      • 定义委托
      • 使用委托类型作为字段/属性(添加“事件”关键字)
      • 您现在公开了用户可以使用“+= MyEventMethod;”挂钩的事件

      希望这会有所帮助,

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-11-20
        • 1970-01-01
        • 2015-09-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多