How to share an event handler between forms

2019-08-09 07:26发布

问题:

I have a Form1.button1 and Form2.button1. I would like to have both buttons share the same event handler for when they are clicked. See comments in the form2.button1_Click event handler.

Form1

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        textBox1.Text = "Hello World";
    }

    private void button2_Click(object sender, EventArgs e)
    {
        Form2 form2 = new Form2(this);
        form2.Show();
    }
}

Form2

public partial class Form2 : Form
{
    Form1 form1;
    public Form2(Form1 form1)
    {
        InitializeComponent();
        this.form1 = form1;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        // how do I get the form2.button1_Click and the form1.button1_Click 
        // to share the same event handler?
    }
}

Any general resources for how to communicate between forms would also be greatly appreciated. All I currently know to do is set variables and methods as public and pass forms to other forms.

回答1:

Given the existing relationship between the two classes, i.e. you are already passing the Form1 reference to the Form2 class constructor, you should expose the Click event as a new event on Form1. That is, encapsulate the actual event with a separate event that wraps the real one.

For example:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    public event EventHandler Button1Click;

    private void button1_Click(object sender, EventArgs e)
    {
        textBox1.Text = "Hello World";

        EventHandler handler = Button1Click;

        if (handler != null)
        {
            handler(this, EventArgs.Empty);
        }
    }

    private void button2_Click(object sender, EventArgs e)
    {
        Form2 form2 = new Form2(this);
        form2.Show();
    }
}

public partial class Form2 : Form
{
    Form1 form1;
    public Form2(Form1 form1)
    {
        InitializeComponent();
        this.form1 = form1;
        this.form1.Button1Click += button1_Click;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        // how do I get the form2.button1_Click and the form1.button1_Click 
        // to share the same event handler?
    }
}

That way, the specific implementation in Form1 can be modified as necessary in the future, without any dependency by any other classes requiring you to fix code elsewhere. All they need to know is that Form1 has the Button1Click event that represents some kind of general clicking action.



回答2:

If you want to single-source the event handling to just one method, then you'll need to change how the event is subscribed to by one of the buttons. A quick way to do this is the following:

  1. In Form1, make button1_Click() public instead of private.
  2. In Form2, add the following line to the constructor:

    public Form2(Form1 form1)
    {
        InitializeComponent();
        this.form1 = form1;
        this.button1.Click += new EventHandler(this.form1.button1_Click);
    }
    


回答3:

I think what you need is to perform same task in both forms. ex : Change textbox from button click of form1 and also from form2

A simpler solution, expose a public method in form1 like follow

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        DoMyWork();
    }

    private void button2_Click(object sender, EventArgs e)
    {
        Form2 form2 = new Form2(this);
        form2.Show();
    }

    // Public method to desired work
    public void DoMyWork() (){
       textBox1.Text = "Hello World";
    }
}

And in form2 use this method like follow (hence you pass form1 to form2)

public partial class Form2 : Form
{
    Form1 form1;
    public Form2(Form1 form1)
    {
        InitializeComponent();
        this.form1 = form1;
        this.form1.Button1Click += button1_Click;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        form1.DoMyWork(); // perform same work
    }
}