set location of Form2 based on Location of Form1?

R

Rich P

In VB.Net I do this from Form2:

...Form1_Load(...)
...
Dim pt As Point
pt.X = Form1.Location.X + 500
pt.Y = Form1.Location.Y + 100
Me.Location = pt

I am currently translating an old app to C# from VB.Net. I tried this
in C#:

...Form1_Load(...)
...
Point pt;
pt.X = Form1.Location.X + 500; <-- error here
pt.Y = Form1.Location.Y + 100; <-- error here
this.Location = pt;

But I get an error message saying that an object reference is required
for a nonstatic field/method/property. Could someone tell me what I
need to do here?

Thanks

Rich
 
J

Jeff Johnson

But I get an error message saying that an object reference is required
for a nonstatic field/method/property. Could someone tell me what I
need to do here?

VB automagically defines a variable with the same name as the form that you
can refer to without ever explicitly creating an instance of that form. C#
does not let you do this. You'll need to make a variable (or list, or array)
of type Form1 and explicitly instantiate it, then use that variable instead
of "Form1".
 
R

Rich P

Well, I figured something out -- I added a public static property pPTto
the form and then added a public static Point var mainPt. I set the
value of mainPt.X = this.Location.X and mainPt.Y = this.Location.Y in
the Form1_Load event. Then when I call Form2 I read the value of pPT in
Form2_Load. That seems to work.

Rich
 
J

Jeff Johnson

Well, I figured something out -- I added a public static property pPTto
the form and then added a public static Point var mainPt. I set the
value of mainPt.X = this.Location.X and mainPt.Y = this.Location.Y in
the Form1_Load event. Then when I call Form2 I read the value of pPT in
Form2_Load. That seems to work.

That is a total Rube Goldberg solution and will break down if you ever open
more than one instance of Form1. You really need to drop some VB habits, not
try to reproduce them in C#.
 
R

Rich P

VB automagically defines a variable with the same name as the form that
you can refer to without ever explicitly creating an instance of that
form. C# does not let you do this. You'll need to make a variable (or
list, or array)
of type Form1 and explicitly instantiate it, then use that variable
instead of "Form1".
<<

So I have Form1 (primary) and Form2 (secondary). Form2 is small
compared to Form1. The goal is to open Form2 in the lower right
quadrant of Form1 - thus, I need to know the location of Form1. Here is
what I am interpreting your suggestion to be:

public static Form1 frm1; //declared in class Form1

Here is where I get confuse: I need to instantiate frm1. I will be
opening and closing Form2. Form1 can get moved around. I am thinking I
could instantiate frm1 at the event where I show Form2:

protected void ShowForm2() [
frm1 = new Form1;
Form2.Show;}

Then in Form2_Load() I get frm1.Location? This is what I will try.
Please correct me if I don't have it straight.



Rich
 
R

Rich P

protected void ShowForm2() [
frm1 = new Form1;
Form2.Show;}
<<

I am having a problem with this method because frm1 is picking up the
default location of Form1 and not the current location. I tried to
assign the current location but got the error message that location is
not a variable. I can get the location using the public property. How
do I get the location using a public static form variable?

Rich
 
J

Jeff Johnson

So I have Form1 (primary) and Form2 (secondary). Form2 is small
compared to Form1. The goal is to open Form2 in the lower right
quadrant of Form1 - thus, I need to know the location of Form1.

If this is the ONLY reason you would need to know anything about Form1 from
Form2, then all you need to do is to create an overload of Form2's
constructor which takes a Point object that specifies Form1's current
location. Form2 would look like this (hideous class name and all):

public Form2()
{ }

public Form2(Point parentLocation)
{
// Do something with the X and Y properties
}

Then, from Form1, you'll do this:

private void ShowForm2()
{
Form2 newForm = new Form2(this.Location);
newForm.Show();
}

Notice that you are creating an instance of Form2 and then using that
instance variable to do things--which is the C# way--not simply using
Form2.Show()--which is the VB way.

Now, the sample I gave you above has a potential flaw: it allows you to
create multiple instances of Form2, which may or may not be what you want.
If you only want a single instance of Form2, you'll have to make the
variable a module-level variable (what C# calls a "field," although I like
the VB-ish term "module-level variable" better since I find it more
descriptive, albeit wordier). So it would look like this:

public class Form1 : Form
{
private Form2 _form2Instance;

private void ShowForm2()
{
if (_form2Instance == null || _form2Instance.IsDisposed)
{
_form2Instance = new Form2(this.Location);
_form2Instance.Show();
}
else
{
_form2Instance.BringToFront();
}
}
}

If you need to know more things about Form1 from Form2, I still recommend
overloading Form2's constructor, this time passing the instance of Form1 to
it:

// Module-level variable
private Form1 _parent;

public Form2(Form1 parent)
{
_parent = parent;
}

Now you can get everything you want to know about Form1 using the _parent
variable. (Well, as long as Form1 exposes data as public or internal....)
 
S

Scott Seligman

Rich P said:
I am having a problem with this method because frm1 is picking up the
default location of Form1 and not the current location. I tried to
assign the current location but got the error message that location is
not a variable. I can get the location using the public property. How
do I get the location using a public static form variable?

Stop trying to pass everything around with global variables:

class Example1 : Form
{
public Example1()
{
Text = "Example 1";
}
}

class Example2 : Form
{
Example1 m_attachTo;

public Example2(Example1 attachTo)
{
m_attachTo = attachTo;
attachTo.Move += new EventHandler(AttachTo_MoveResize);
attachTo.Resize += new EventHandler(AttachTo_MoveResize);
Load += new EventHandler(Example2_Load);

Text = "Example 2";
}

void Example2_Load(object sender, EventArgs e)
{
Left = m_attachTo.Right;
Top = m_attachTo.Top;
}

void AttachTo_MoveResize(object sender, EventArgs e)
{
if (m_attachTo.WindowState == FormWindowState.Normal)
{
Left = m_attachTo.Right;
Top = m_attachTo.Top;
}
}
}

static void ExampleMethod()
{
Example1 example1 = new Example1();
example1.Show();

Example2 example2 = new Example2(example1);
example2.Show();
}
 
R

Rich P

Thank you all for your replies. Yes, I had considered the constructor
thing. I HAVE doen this in VB, but -- being lazy, I liked the VB Form
var technique. But it sounds like in C# passing a form to the other
form's constructor is the way to go. And yes, I only want one instance
of form2. Here is what I have been doing (in VB) which seems to work in
C#

//actual form names
private void radAreaCodes_Click(object sender, EventArgs e)
{
if (frmAcodes == null)
{
frmAcodes = new frmAreaCodes();
frmAcodes.FormClosed += frm_Closed;
frmAcodes.Show();
}
else
frmAcodes.BringToFront();
}

private void frm_Closed(object sender, FormClosedEventArgs e)
{
Form frm = (Form)sender;
if (frm.Name.Equals("frmAreaCodes")) frmAcodes = null;
if (frm.Name.Equals("anotherfrm")) anotherfrm = null;
..
}


so, I will pass "this" in

frmAcodes = new frmAreaCodes(this);

I have to do this for multiple forms (all different), thus I use
frm_Closed to remove the respective form from the heap (stack ...) once
I close that form (is this a VB technique?). Please advise if there is
a better technique for this in C# when closing a form or if this
technique will suffice


Rich
 
J

Jeff Johnson

I have to do this for multiple forms (all different), thus I use
frm_Closed to remove the respective form from the heap (stack ...) once
I close that form (is this a VB technique?). Please advise if there is
a better technique for this in C# when closing a form or if this
technique will suffice

I believe what you're doing in the frm_Closed handler is what I was
accounting for by testing the IsDisposed property of the variable in the
sample code I gave you. When is form is closed it will be disposed, so I
checked for that and created a new form if so.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top