3

I have two buttons in Form 1, one is "ShowForm2" button and one is "button1" button.

Button 1 is disable by default. And when I click "ShowForm2" button, Form 2 will show.

PrntScn of my form 1

So, what I want is, when I click the "button2" in form 2, it will enable the "button1" in form 1.

enter image description here

So, I try to code like this in my form2 class:

public partial class Form2 : Form
{
    bool enable_form1_button1;
    public bool Enable_form1_button1
    {
        get { return this.enable_form1_button1; }
        set { this.enable_form1_button1 = value; }
    }
    public Form2()
    {
        InitializeComponent();
    }

    private void button2_Click(object sender, EventArgs e)
    {
        enable_form1_button1 = true;
    }
}

Then in my Form1 class, I am expecting to get the "enable_form1_button1 = true" to pass into form 1 and enable my form 1 button1. But how to do this?

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

    private void btb_Showfrm2_Click(object sender, EventArgs e)
    {
        Form2 frm2 = new Form2();
        frm2.Show();
        button1.Enabled = frm2.Enable_form1_button1; // I put it here, and it just does not seems right
    }
}
jhyap
  • 3,779
  • 6
  • 27
  • 47
  • You could make a method like `public void SetButton1Enabled(bool enabled) { button1.Enabled = enabled; }` inside `Form1` and call that inside the `button2_Click` method of `Form2` (`Form2` needs a reference to the `Form1` object it was called from). Or work with events/delegates. – Corak May 19 '13 at 06:01
  • 1
    it cannot see any public method of Form1 inside Form2 even I have set the modifier to be public for button2 in form2 – jhyap May 19 '13 at 06:08
  • 1
    `Form1` and `Form2` are classes and you can't call a (non static; but don't go there!) method on a class. You need an `instance` of that class. And so the `frm2`-instance needs a reference to the calling instance of the `Form1` class on which it then is able to call the method. Or if `button1` is public, directly set `frm1.button1.enabled = true;`. – Corak May 19 '13 at 06:14

5 Answers5

6

Well what you can do is, expose the button as a property and send a reference of your current form to the form that needs to take control:

Form1

public partial class Form1 : Form
{        
    public Button BtnShowForm2
    {
        get { return btnShowForm2; }
        set { btnShowForm2 = value; }
    }

    private void btnShowForm2_Click(object sender, EventArgs e)
    {
        // pass the current form to form2
        Form2 form = new Form2(this);
        form.Show();
    }
}

Then in Form2:

public partial class Form2 : Form
{
    private readonly Form1 _form1;

    public Form2(Form1 form1)
    {
        _form1 = form1;
        InitializeComponent();
    }

    private void btnEnabler_Click(object sender, EventArgs e)
    {
        // access the exposed property here <-- in this case disable it
        _form1.BtnShowForm2.Enabled = false;
    }
}

I hope this is what you're looking for.

Dimitar Dimitrov
  • 14,868
  • 8
  • 51
  • 79
4

Form1.cs

    public partial class Form1 : Form
    {
    public Form1()
    {
        InitializeComponent();
        button1.Enabled = false;
    }

    private void button2_Click(object sender, EventArgs e)
    {
        Form2 oFrm2 = new Form2();
        oFrm2.evtFrm += new ShowFrm(oFrm2_evtFrm);
        oFrm2.Show();
    }

    void oFrm2_evtFrm()
    {
        button1.Enabled = true;
    }
}

Form2.cs

    public delegate void ShowFrm();
    public partial class Form2 : Form
    {
    public event ShowFrm evtFrm;
    public Form2()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        if (evtFrm != null)
        {
            evtFrm();
        }
    }
}
Mukesh Sakre
  • 156
  • 2
  • 13
  • This is the way to go. Form1 is the boss, it only subscribes to _an_ event in Form2 and Form2 is never in control of what happens in Form1. – Gert Arnold May 19 '13 at 18:39
  • even though the public get set sounds more familiar to me, but it seems that using delegate should be the practice – jhyap May 22 '13 at 04:22
  • Once again , doing get set would be a workaround to do this. Because you will have to exchange the reference of both the class. And also its not the job of Form2's class to enable/disable Form1's controls. Only Form1 should be responsible for playing with its controls. Form2 only can tell to Form1 that this needs to be done. – Mukesh Sakre May 22 '13 at 04:57
  • Not sure is it my illusion or what. After I changed all the public get set to use delegate, the application seems running smoother :) – jhyap Jun 04 '13 at 05:11
  • Could you explain what you are doing? – Jonathan Oct 15 '19 at 17:37
1

you can send a refrence of your form1 to your form2 in the from2 constructor for example : and then in button clicked event handler in form2 call a public method in form1 to enable the button :

this could be your form1 code :

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

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

        public void enableButton()
        {
            button2.Enabled = true;
        }

this could be your form2 code :

public partial class Form2 : Form
    {
        private Form1 frm;
        public Form2(Form1 frm)
        {
            InitializeComponent();

            this.frm = frm;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            frm.enableButton();
        }
hm1984ir
  • 554
  • 3
  • 7
0

If you'll only have one instance of Form1 you can also get away with having a static Button member in Program which references the button you want to enable from Form2.

Form1.cs:

using System;
using System.Windows.Forms;

namespace StackOverflow_2013_05_19_Form1_Form2_buttons
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            button2.Enabled = false;

            Program.button = button2;
        }

        private void button1_Click(object sender, EventArgs e)
        { new Form2().Show(); }

        private void button2_Click(object sender, EventArgs e) { }
    }
}

Form2.cs:

using System;
using System.Windows.Forms;

namespace StackOverflow_2013_05_19_Form1_Form2_buttons
{
    public partial class Form2 : Form
    {
        public Form2()
        { InitializeComponent(); }

        private void button1_Click(object sender, EventArgs e)
        { Program.button.Enabled = true; }
    }
}

Program.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace StackOverflow_2013_05_19_Form1_Form2_buttons
{
    static class Program
    {
        public static Button button;

        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}
dharmatech
  • 8,979
  • 8
  • 42
  • 88
0

I would recommend you to use event/delegates to perform this task. This is the standard way of doing so.

Again passing reference in constructor or making static func/var/properties are just workaround and Called as bad programming.

Mukesh Sakre
  • 156
  • 2
  • 13
  • Could you provide some sample code on how to use the delegate to pass data on this example? Previously, I did tried to use delegate (referring some online source) but it just does not seems to be worked. – jhyap May 19 '13 at 08:44