Call method on another form that is still open?

2020-04-18 03:32发布

问题:

So, I have two forms -- one that is open, and another that is essentially just a popup on the second one. The second form opens with a maskedtextbox inside it, plus Save and Cancel buttons -- I want Save to change a field on the first form.

As far as I know, I have to use a second form for my popup since what I want to accomplish isn't as simple as something I could put in a MessageBox -- if there is another option, I'm all ears.

What I've been trying:

Form 1:

public partial class Form1 : Form
{
   public void ChangeLabel()
   {
       label1.Text = StaticVariables.labelString;
   }
}

Form 2:

public partial class Form2 : Form
{
   private void changeForm1_Click(object sender, EventArgs e)
   {
      StaticVariables.labelString = textBox.Text; 
      Form1 frm = new Form1();
      frm.ChangeLabel();
   }
}

Obviously, that hasn't worked.

回答1:

There's no need for the second form to know about the first form at all. Having it know about it complicates its code, and needlessly ties it to that form. Having another form knowing about the internal UI components of the main form is even worse; if you do that then changes to how the main form displays the data would break this other form. Just have the popup have a property representing the value that lets it be set/fetched externally:

public partial class Form2 : Form
{
    public string Result //TODO give better name
    {
        get { return textBox.Text; }
    }
    public string DisplayText //TODO give better name
    {
        get { return label.Text; }
        set { label.Text = value; }
    }
}

Then the main form can set the display value, show the form, and fetch the resulting value:

Form2 popup = new Form2();
popup.DisplayText = "asdf";
popup.ShowDialog();
myField = popup.Result;


回答2:

You need to create a new constructor that receives an instance of Form1 and store that as a field in Form2. Then, when you want to change the label use the instance that was passed in. I'm answering from my phone so when I get to my desk I can elaborate with code.

But what's happening here is that you're creating a new Form1 and setting the value.

private Form1 _form1;

...

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

...

private void changeForm1_Click(object sender, EventArgs e)
{
    StaticVariables.labelString = textBox.Text; 
    _form1.ChangeLabel();
}

and then finally, when you launch Form2:

var form2 = new Form2(this);
form2.Show();