C# – Best way to communicate between forms

cuser interfacewinforms

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't have much experience with GUI.
I have one main form (and possibly more in the future) from which other sub-forms open (and they might have sub-forms of themselves) and I wonder what is, in your opinion, the best way to communicate between them?

I thought of passing the main form as a parameter to the constructors of the sub-forms, but it doesn't seem like a good way, especially if I'm going to need to communicate between other, distinct, sub-forms, not to mention I have to double check the input, or make a few methods, but it seems more like functional programming than object oriented programming…

Perhaps I can:

  • Create a static class (or Properties.Settings) for global settings. Cons: every change of data is needed to be copied to the class, I'm looking for something a bit more comfortable and elegant.
  • Use the ugly way of accessing the controls from Application.OpenForms – fixes the problem of passing the main form as parameter. Cons: not very stable.
  • Do something else I haven't thought of. Suggestions? Cons: don't know what it is yet.

Best Answer

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
    }
}