I have an application that has a main form and uses an event handler to process incoming data and reflect the changes in various controls on the main form. This works fine.
Consider using loosely coupled events. This will allow you to couple the classes in such a way that they never have to be directly aware of each other. The Unity application block comes with an extension called EventBroker that makes this very simple.
Here's a little lick of the sugar:
public static class EVENTS
{
public const string UPDATE_TICKED = "event://Form1/Ticked";
}
public partial class Form1 : Form
{
[Publishes(EVENTS.UPDATE_TICKED)]
public event EventHandler Ticked;
void the_timer_Tick(object sender, EventArgs e)
{
// I would like code in here to update all instances of SecondaryForm
// that happen to be open now.
MessageBox.Show("Timer ticked");
OnTicked();
}
protected virtual void OnTicked()
{
if (Ticked == null) return;
Ticked(this, e);
}
}
public partial class SecondaryForm : Form
{
[SubscribesTo(EVENTS.UPDATE_TICKED)]
private void Form1_Ticked(object sender, EventHandler e)
{
// code to handle tick in SecondaryForm
}
}
Now if you construct both of these classes using Unity, they will automatically be wired together.
Update
Newer solutions use message bus to handle loosely coupled events. See http://masstransit-project.com/ or http://nimbusapi.github.io/ as examples.
I guess you can make SecondaryForm take in the parent form in the constructor, and the add an event handler in the constructor.
private void start_form_button_Click(object sender, EventArgs e)
{
SecondaryForm new_form = new SecondaryForm(this);
new_form.Show();
}
In SecondaryForm.cs:
public SecondaryForm(ISomeView parentView)
{
parentView.SomeEvent += .....
}
class SecondForm
{
private FirstForm firstForm;
public SecondForm()
{
InitializeComponent();
// this means unregistering on form closing, uncomment if is necessary (anonymous delegate)
//this.Form_Closing += delegate { firstForm.SomeEvent -= SecondForm_SomeMethod; };
}
public SecondaryForm(FirstForm form) : this()
{
this.firstForm = form;
firstForm.Timer.Tick += new EventHandler(Timer_Tick);
}
// make it public in case of external event handlers registration
private void Timer_Tick(object sender, EventArgs e)
{
// now you can access firstForm or it's timer here
}
}
class FirstForm
{
public Timer Timer
{
get
{
return this.the_timerl
}
}
public FirstForm()
{
InitializeComponent();
}
private void Button_Click(object sender, EventArgs e)
{
new SecondForm(this).ShowDialog(); // in case of internal event handlers registration (in constructor)
// or
SecondForm secondForm = new SecondForm(this);
the_timer.Tick += new EventHandler(secondForm.Timer_tick); // that method must be public
}