简体   繁体   English

C#,如何创建一个事件并在另一个类中侦听它?

[英]C#, How to create an event and listen for it in another class?

I can't figure out how to do this, heres sample code. 我不知道如何执行此操作,这是示例代码。 Of what I wish to do. 我想做的。

public Class MainForm : Form
{
    MyUserControl MyControl = new MyUserControl;
    private void Button_Click(object sender, EventArgs e)
    {
        //Create MyEvent
    }    
}

public Class MyUserControl : UserControl
{
    //listen for MyEvent from MainForm, and perform MyMethod
    public void MyMethod()
    {
         //Do Stuff here
    }
}

Step 1) Expose an event on MainForm... say.. 步骤1)在MainForm上公开一个事件。

public event Action simpleEvent

Step 2) Give MyUserControl a constructor that takes an instance of MainForm and bind an action to that event 步骤2)给MyUserControl一个构造函数,该构造函数采用MainForm的一个实例并将一个操作绑定到该事件

public MyUserControl(MainForm form) {
    form += () => Console.WriteLine("We're doing something!")
}

Step 3) raise the event in MainForm.Button_Click 步骤3)在MainForm.Button_Click中引发事件

if(simpleEvent != null) simpleEvent();

Note: You could register your own delegates and work with something other than lambda expressions. 注意:您可以注册自己的委托并使用lambda表达式以外的其他东西。 See http://msdn.microsoft.com/en-us/library/17sde2xt.aspx for a more thorough explanation 请参阅http://msdn.microsoft.com/en-us/library/17sde2xt.aspx了解更详尽的说明

Your end result would look like... 您的最终结果将看起来像...

public Class MainForm : Form
{
    public event Action MyEvent;

    MyUserControl MyControl = new MyUserControl(this);
    private void Button_Click(object sender, EventArgs e)
    {
        if(simpleEvent != null) simpleEvent();
    }    
}

public Class MyUserControl : UserControl
{
    //listen for MyEvent from MainForm, and perform MyMethod
    public MyUserControl(MainForm form) {
        simpleEvent += () => MyMethod();
    }

    public void MyMethod()
    {
         //Do Stuff here
    }
}

This is how to delegate to an event of a private member, so the outside can listen to it. 这是将事件委派给私人成员的事件的方法,以便外界可以收听。

public event EventHandlerType EventHandlerName
{
    add
    {
        this._privateControl.EventHandlerName += value;
    }
    remove
    {
        this._privateControl.EventHandlerName -= value;            
    }
}

Another option would be to have an event in your form class: 另一个选择是在表单类中有一个事件:

public event EventHandler MyEvent;

And listen to the private member's event: 并聆听私人会员的活动:

this._customControl.SomeEvent += this.SomeEventHandler;

With this: 有了这个:

private void SomeEventHandler(object sender, EventArgs e)
{
    if (this.MyEvent != null)
    {
        this.MyEvent(this, e);
    }
}

The usage from the outside in both cases will be the same: 两种情况下,外部使用情况都相同:

var form = new Form1();

form1.MyEvent += (o, e) => { Console.WriteLine("Event called!"); };

The bottom line is the you must implement functionality inside your form to allow the outside subscribe/listen to inner events. 最重要的是,您必须在表单内部实现功能,以允许外部订阅/收听内部事件。

//listen for MyEvent from MainForm, and perform MyMethod

That's the wrong way around. 那是错误的方法。 Publishing an event in control is useful, the control cannot possibly guess how it is going to get used. 在控件中发布事件非常有用,该控件无法猜测如何使用它。 It however most certainly should not know anything about an event that may or may not be available in the form that it gets dropped on. 但是,由于它肯定应该知道这些可能或不可能的,因为它被丢弃的形式提供的事件东西。 That has the nasty habit of blowing up when the form just doesn't (yet) have the event. 这有一个讨厌的习惯,那就是当表单还没有发生事件时就炸毁它。 The bad kind too, a crash at design time that puts up the White Screen of Darn and prevents you from fixing the problem. 同样不好的一种,是设计时发生的崩溃,使“达恩白屏”(White Screen of Darn)停滞不前,无法解决问题。

A form doesn't have to guess, it knows exactly what controls it has. 表单不必猜测,它确切知道它拥有什么控件。 So where ever in the form you might want to raise the event, just call the control's MyMethod method directly. 因此,无论您希望在表单中的哪个位置引发事件,只需直接调用控件的MyMethod方法。 And if that's wrong for some reason, like removing the control but not the call, then you just get a compile error that's easy to fix. 如果由于某种原因(例如删除控件而不是调用)而错了,那么您只会得到易于修复的编译错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM