sd_dracula
sd_dracula

Reputation: 3896

Cross form communication

I have a program with two forms. The second form, Form2 in which I want a few labels initialized with values from the main form.

The code:

public Form2()
        {
            InitializeComponent();
            Form1 mainForm = (Form1)this.Owner;
            lblName.Text = mainForm.gvRow.Cells[2].Value.ToString();
            lblItemType.Text = mainForm.gvRow.Cells[1].Value.ToString();
            lblLocation.Text = mainForm.gvRow.Cells[3].Value.ToString();
        }

For some reason this does not work in the Form2() section, this.Owner is null. But if I was to place the code in an event method it works just fine.

How can I fix that?

Upvotes: 0

Views: 675

Answers (7)

ispiro
ispiro

Reputation: 27633

This code is executed when the Form2 form is created. The Owner isn't set yet (and, presumably, the data isn't present yet). If you put it in the VisibleChanged event handler - it will be executed when the Owner and data are (presumably) present.

Upvotes: 2

sotn0r
sotn0r

Reputation: 109

Use the Form.Show(IWin32Window) overload to pass the owner to the child form.

http://msdn.microsoft.com/en-us/library/szcefbbd(v=vs.110).aspx

Upvotes: 0

Laoujin
Laoujin

Reputation: 10229

You need to set the Owner property yourself

As an alternative you could pass a reference to Form1 to the Form2 constructor. In the code that opens Form2 you probably have something like this:

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

You could replace that with:

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

In Form2 you'd add a constructor overload:

public Form2(Form1 owningForm)
{
     InitializeComponent();
     Form1 mainForm = owningForm;
     lblName.Text = mainForm.gvRow.Cells[2].Value.ToString();
     lblItemType.Text = mainForm.gvRow.Cells[1].Value.ToString();
     lblLocation.Text = mainForm.gvRow.Cells[3].Value.ToString();
}

If different "owning forms" are possible you may need to define an interface instead of passing Form2.

Upvotes: -1

Karim AG
Karim AG

Reputation: 2193

That's because the Owner is not initialized yet in the Form2 constructor, set your code in your Form2_Load event

Upvotes: 1

mike1952
mike1952

Reputation: 513

Owner isn't set until the form is shown - i.e. in ShowDialog, not during the constructor. You should pass the parent as a parameter in the constructor:

public Form2(Form1 mainForm)
{
    InitializeComponent();
    lblName.Text = mainForm.gvRow.Cells[2].Value.ToString();
    lblItemType.Text = mainForm.gvRow.Cells[1].Value.ToString();
    lblLocation.Text = mainForm.gvRow.Cells[3].Value.ToString();
}

Upvotes: 1

LunicLynx
LunicLynx

Reputation: 1098

Use the Load Event. The Owner is only initialized after you Show the form, which then in return raises the Load Event.

Upvotes: 1

Servy
Servy

Reputation: 203802

The second form shouldn't need to even know about your main form in the first place. Even if it did, it's an extremely bad idea to be reading into its internal controls.

Instead your second form should have public properties through which it can accept the data that your main form wants to provide to it, without exposing any of its internal controls, and the main form can set those properties using the data from its controls. You could also potentially use parameters to the constructor instead, if you have just a bit of data, and that is the only time you need to provide it.

public class Form2
{
    public string Name
    {
        get { return lblName.Text; }
        set { lblName.Text = value; }
    }
}

public class MainForm
{
    public void Foo()
    {
        Form2 child = new Form2();
        child.Name = mainForm.gvRow.Cells[2].Value.ToString();
        child.Show();
    }
}

Upvotes: 4

Related Questions