I almost never used (advanced, or at all) graphical interfaces, or one simple form with simple controls... but this time I\'ve got something a little more complex, and I don
You can use the built in Tag property of the form which is an "object" class.
public Form1() { (ComplicatedDataStructure)Tag = new ComplicatedDataStracture(); } . . form1 = new Form1(); . . form2 = new Form2(); . . form2.Tag = form1.Tag;
so form2.Tag is equals to "ComplicatedDataStracture" object;
The most flexible, scalable (and IMHO the most professional) way to do it is to use CAB (Composite Application Block). In simple terms CAB is a set of 2-3 assemblies that implement a lot of plumbing required to make complex UI applications the right way and it exposes this plumbing to the user of the library in a nice way. Among others it has a very nice event and command (as in command pattern) system.
The downside: requires some time to learn and not very trivial to grasp.
Here is a comprehensive (but easy to understand) tutorial that will help you make the learning easier.
Your constructor idea is probably the most sound method of communication back to the main form. Your sub form would do something like the following:
public class SubForm : Form
{
public SubForm(MainForm parentForm)
{
_parentForm = parentForm;
}
private MainForm _parentForm;
private void btn_UpdateClientName_Click(object sender, EventArgs e)
{
_parentForm.UpdateClientName(txt_ClientName.Text);
}
}
And then you expose public methods on your MainForm
:
public class MainForm : Form
{
public void UpdateClientName(string clientName)
{
txt_MainClientName.Text = clientName;
}
}
Alternatively, you can go the other way around and subscribe to events from your SubForms:
public class MainForm : Form
{
private SubForm1 _subForm1;
private SubForm2 _subForm2;
public MainForm()
{
_subForm1 = new SubForm1();
_subForm2 = new SubForm2();
_subForm1.ClientUpdated += new EventHandler(_subForm1_ClientUpdated);
_subForm2.ClientUpdated += new EventHandler(_subForm2_ProductUpdated);
}
private void _subForm1_ClientUpdated(object sender, EventArgs e)
{
txt_ClientName.Text = _subForm1.ClientName; // Expose a public property
}
private void _subForm2_ProductUpdated(object sender, EventArgs e)
{
txt_ProductName.Text = _subForm2.ProductName; // Expose a public property
}
}
A good way is to declare delegates in the form that want to start the communication. You need a delegate and a callback function:
public delegate void SetValueDelegate(string value);
public SetValueDelegate SetValueCallback;
Another form can then attach to this delegate. At that moment both forms have to know each other, but not after that moment:
firstForm.SetValueCallback += new SetValueDelegate(secondForm.SetValueFunction);
The second form has to declare a function that matches the delegate definition:
public void SetValueFunction(string value)
{
// do something
}
Now the first form can use the delegate to use the function of the second form (and all other forms or classes that were attached to the delegate:
SetValueCallback(txtParam.Text);
Edit: made an complete example
using System;
namespace DelegateTest
{
public delegate void SetValueDelegate(string value);
public class Class1
{
public SetValueDelegate SetValueCallBack;
public void Test()
{
if(SetValueCallBack != null)
{
SetValueCallBack("Hello World!");
}
}
}
public class Class2
{
public void SetValueFunction(string value)
{
Console.WriteLine(value);
}
}
public class Launcher
{
public static void Main(string[] args)
{
Class1 c1 = new Class1();
Class2 c2 = new Class2();
c1.SetValueCallBack += new SetValueDelegate(c2.SetValueFunction);
c1.Test();
}
}
}