Listening to Events in Main Form from Another Form in C#

我是研究僧i 提交于 2019-11-29 12:01:01
class SecondForm
{
  private FirstForm firstForm;

  public SecondForm()
  {
    InitializeComponent();
    // this means unregistering on form closing, uncomment if is necessary (anonymous delegate)
    //this.Form_Closing += delegate { firstForm.SomeEvent -= SecondForm_SomeMethod; };
  }

  public SecondaryForm(FirstForm form) : this()
  {
    this.firstForm = form; 
    firstForm.Timer.Tick += new EventHandler(Timer_Tick);
  }

  // make it public in case of external event handlers registration
  private void Timer_Tick(object sender, EventArgs e)
  {
    // now you can access firstForm or it's timer here
  }
}

class FirstForm
{
  public Timer Timer
  {
    get
    {
      return this.the_timerl
    }
  }

  public FirstForm()
  {
    InitializeComponent();
  }

  private void Button_Click(object sender, EventArgs e)
  {
    new SecondForm(this).ShowDialog(); // in case of internal event handlers registration (in constructor)
    // or
    SecondForm secondForm = new SecondForm(this);
    the_timer.Tick += new EventHandler(secondForm.Timer_tick); // that method must be public
  }

Consider using loosely coupled events. This will allow you to couple the classes in such a way that they never have to be directly aware of each other. The Unity application block comes with an extension called EventBroker that makes this very simple.

Here's a little lick of the sugar:

public static class EVENTS
{
    public const string UPDATE_TICKED = "event://Form1/Ticked";
}

public partial class Form1 : Form
{
    [Publishes(EVENTS.UPDATE_TICKED)]
    public event EventHandler Ticked; 

    void the_timer_Tick(object sender, EventArgs e)
    {
        // I would like code in here to update all instances of SecondaryForm
        // that happen to be open now.
        MessageBox.Show("Timer ticked");
        OnTicked();
    }

    protected virtual void OnTicked()
    {
        if (Ticked == null) return;
        Ticked(this, e);
    }
}

public partial class SecondaryForm : Form
{
    [SubscribesTo(EVENTS.UPDATE_TICKED)]
    private void Form1_Ticked(object sender, EventHandler e)
    {
        // code to handle tick in SecondaryForm
    }
}

Now if you construct both of these classes using Unity, they will automatically be wired together.

Update

Newer solutions use message bus to handle loosely coupled events. See http://masstransit-project.com/ or http://nimbusapi.github.io/ as examples.

I guess you can make SecondaryForm take in the parent form in the constructor, and the add an event handler in the constructor.

private void start_form_button_Click(object sender, EventArgs e)
{
    SecondaryForm new_form = new SecondaryForm(this);
    new_form.Show();
}

In SecondaryForm.cs:

public SecondaryForm(ISomeView parentView)
{
    parentView.SomeEvent += .....
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!