Another form question

  • Thread starter Thread starter AMP
  • Start date Start date
A

AMP

Hello,
Form1 has a button that creates Form2 that has a button that changes a
lable on Form1.
How do I give(send) Form2 a reference to Form1?
Thanks
Mike
 
Mike,

You will need to create a method, property, or a parameter on your
constructor that will accept the reference to Form1 to change. When you
create Form2, you need to pass the reference to Form1 through the
constructor, property, or method. Something like:

public class Form2 : Form
{
public Form2(Form1 form1)
{
// Store form1.
}
}

Then you can pass Form1 through the constructor.

Hope this helps.
 
Thanks,
Is this the standard way of passing object references around and
keeping track of them? You have been a big help.Are there any good
resourses that deal with specifally this issue?
Thanks
Mike
 
Hi,

AMP said:
Thanks,
Is this the standard way of passing object references around and
keeping track of them?


Yes it's , also note that you need to either make your label in form 1
public or use a property to expose it (this is the preferred method)
 
Note that you also *must* have a no-argument constructor for your form
in order to keep Visual Studio Designer happy, which is why I prefer
Nicholas's other suggestion: a property.

There are two ways to do this: one is the "cheap and nasty" solution,
which looks something like this:

public class Form1 : System.Windows.Form
{
public string LabelText
{
get { return this.label1.Text; }
set { this.label1.Text = value; }
}

...

Form2 myForm2 = new Form2();
myForm2.Form1 = this;
myForm2.Show();
...
}

public class Form2 : System.Windows.Form
{
Form1 _form1Instance;

public Form2()
{
this._form1Instance = null;
}

public Form1 Form1
{
get { return this._form1Instance; }
set { this._form1Instance = value; }
}

...

private void button1_Click(object sender, System.EventArgs e)
{
if (this._form1Instance != null)
{
this._form1Instance.LabelText = "Button 1 Clicked";
}
}

Unfortunately, this solution doesn't scale very well. What if you want
button1 to set the text in labels on three different Form1's currently
showing, or you want to have it set text on Form1 and bold a field on
Form3? The thing quickly gets out of control.

Here is a sketch of a cleaner solution (although a bit more advanced):

public class Form1 : System.Windows.Form
{
private void myForm2_UserSaysSo(object sender, System.EventArgs e)
{
this.label1.Text = "User Clicked Button";
}

Form2 myForm2 = new Form2();
myForm2.UserSaysSo += new System.EventHandler(myForm2_UserSaysSo);
myForm2.Show();
...
}

public class Form2 : System.Windows.Form
{
public event System.EventHandler UserSaysGo;

private void button1_Click(object sender, System.EventArgs e)
{
if (this.UserSaysSo != null)
{
this.UserSaysSo(this, System.EventArgs.Empty);
}
}
}

The point here is that Form2 exposes an event that occurs whenever the
user clicks the button. Any other form can then listen for that event
and react to it. If you have to get information out of Form2 when that
happens, just have Form2 expose properties. You can get a reference to
Form2 by casting the "sender" argument within the event handler, like
this:

Form2 form2thatRaisedEvent = (Form2)sender;

Now you can have any number of other forms and objects listening for
that button click, without having to make extensive changes to Form2
every time you have a new requirement.

By the way, I called the event, etc. "UserSaysSo" (which is a lame
name) because it's really bad style to call it "Button1Clicked". You
should name your events, and in fact every public event, property, and
method of your Form, based on what it _means_ to an outside observer,
not based on how it's _implemented_ on your form. Today's button click
may change to a keypress tomorrow. You want to have events called
"FormCompleted", "UserCanceled", "RequestForDetails", etc., and
properties called "CompanyName", "DueDate", etc.
 
BTW, is this a homework assignment? I see someone else in
microsoft.public.dotnet.csharp.general asking exactly the same
question. :)
 
Back
Top