Mega
Mega

Reputation: 565

Invoke button from another Form in C#

I'm trying to invoke button from a different Form than it was created. I have application with two forms:

The "Second" Form is invoked from the "Main" Form with the code:

Second run_second_form = new Second();
run_second_form.Show();

On the "Main" Form I have a button "Button1". Is it possible this button to be invoked from the "Second" Form?

I can easily invoke "Button1" from the "Main" Form where it is created, with the code:

Button1.PerformClick();

but I'm not able to do it from the "Second" Form. I tried with:

Main.Button1.PerformClick();

but it says "The name "Button1" does not exists in the current context".

Upvotes: 1

Views: 3829

Answers (3)

Ctznkane525
Ctznkane525

Reputation: 7465

Button1 is not visible by the other form as it's modifier is not public or internal but this isn't how you want to do this anyway.

I'd have the second form fire an event, and have the first form have an event handler to the instance of the second form.

That way, there's no bidirectional dependence created between the two forms.

Here's an example:

Event Class:

public class ActionToCallEvent : EventArgs
{
    private ActionToCallEvent() {}
}

In Form 2:

public static event EventHandler<ActionToCallEvent> ActionToCall; 

private static void OnActionToCall(EventArgs e) 
{
   if (ActionToCall != null)
      ActionToCall(this, e);
}

You'll be calling OnActionToCall in Form2 when you need to use the method from 1.

In Form 1, when instantiating the Form2 instance:

Form2 form2 = new Form2();
form2.ActionToCall += Form2EventHandler;

And this is the method in Form1 to capture the event handling:

private void Form2EventHandler(object sender, ActionToCallEvent e)
{
    // Call Your Code Here!
}

Upvotes: 4

Enigmativity
Enigmativity

Reputation: 117174

So, the first thing is that controls, when added to forms using the designer, are added as "Private". For the control to be accessible outside of the the for Main you need change the accessibility.

Accessibility

Change it from "Private" to either "Internal" (preferred if the two forms are in the same assembly) or "Public" if they are not.

Then you should be able to access the Button1 control on main form.

The only thing that you don't show is how you keep a reference to Main to be able to call Main.Button1.PerformClick().

After changing the accessibility in the designer, here's the code I used to test this:

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

    internal Main Main { get; set; }

    private void button1_Click(object sender, EventArgs e)
    {
        if (this.Main != null)
        {
            this.Main.Button1.PerformClick();
        }
    }
}

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

    private void Main_Load(object sender, EventArgs e)
    {
        Second run_second_form = new Second();
        run_second_form.Main = this;
        run_second_form.Show();
    }

    private void Button1_Click(object sender, EventArgs e)
    {
        MessageBox.Show("Clicked on Main");
    }
}

That worked for me.

Having said all this though, I think Ctznkane525's solution is probably a better one for what you need. It's generally better to avoid passing references to forms around like this. Main should just respond to an event from Second.

Upvotes: 2

Hursey
Hursey

Reputation: 551

Well, firstly you probably want to move the logic out of the button click event into it's own method. Secondly, you really just need to pass a reference from the Main form to the Second form.

There are a few options on this.

 Second run_second_form = new Second();
 run_second_form.Show(this); //Makes the main form the owner of second_form

Then in your second form

Mainform mainForm = (MainForm)this.Owner;
mainform.Button1.PreformClick

Upvotes: 0

Related Questions