tags:

views:

196

answers:

3

Given a public instantiation of a class in WinForm1, I attempt to open WinForm2 and eliciting DB parms do a query the results of which I would like use to fill the class instance in WinForm1. However, I cannot figure out how to access the class instance in WinForm1 from WinForm2.

The class instance in WinForm1 is coded as a private member / public property:

private theClass _classInstance;
public theClass ClassInstance {get; set;}

I am calling WinForm2 as a modal form.

WinForm2 wf2 = new WinForm2();
wf2.ShowDialog(this);

Is there way I can refer to ClassInstance (modifying its value) while in wf2 ??

+2  A: 

You could pass a reference to the parent form in the constructor or as a property to the child form or hold the reference in a static field.

class WinForm2 : Form {
     WinForm1 parentForm;
     public WinForm2(WinForm1 parentForm) {
         this.parentForm = parentForm;
         // ....
     }

     // Use `parentForm.ClassInstance` here.
}


WinForm2 wf2 = new WinForm2(this);
wf2.ShowDialog(this);

By the way, when you're declaring an automatic property like the one you specified, you shouldn't manually create a backing field. The compiler takes care of that for you.

Mehrdad Afshari
heh. You got to it a bit quicker, but don't forget that the constructor still needs to call InitializeComponent. You can do it the way I did below by chaining the constructors or do it manually in the body of the new constructor, but leaving it out will hurt.
Jacob Proffitt
@Jacob: The "//...." I wrote means other stuff in the constructor ;)
Mehrdad Afshari
I know. I just want to make that explicit as it's an easy gotcha to avoid.
Jacob Proffitt
Passing forms around is a terrible idea because it leads to terrible design. Pass what you want from the first form into the second, either as constructor parameters, passing references to properties on the second form or in a separate object, or anything but passing UI elements around.
Richard Hein
@Richard: I agree. I just answered the question about how you could do that. In terms of design, sure, it's a bad idea.
Mehrdad Afshari
A: 

You can create a constructor on WinForm2 that accepts a WinForm1 on instantiation.

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

    Form parentForm
    internal WinForm2(Form parent)
        : this()
    {
        parentForm = parent
    }
}
Jacob Proffitt
A: 

in WinForm2 (improved to avoid possible runtime failures that Mehrdad pointed out):

WinForm1 form1 = this.Owner as WinForm1;
if (form1 != null) {
    theClass classInstance = form1.ClassInstance;
    // ...
}

Owner property returns the form which was passed to ShowDialog(IWin32Window window)

Utaal
I wouldn't do it this way if the form is *required* to have a parent form of type WinForm1. This might fail at runtime if that's not the case but the constructor approach forces the child form to be created with a known parent form.
Mehrdad Afshari
You are absolutely right, I've just improved my answer: I'd still prefer not touching the constructor to permit the creation of the dialog without an attached WinForm1
Utaal