Écoute d’événements dans le formulaire principal à partir d’un autre formulaire en C #

J’ai une application qui a un formulaire principal et utilise un gestionnaire d’événements pour traiter les données entrantes et refléter les modifications apscopes aux divers contrôles du formulaire principal. Cela fonctionne bien.

J’ai aussi un autre formulaire dans l’application. Plusieurs instances de ce second formulaire peuvent être exécutées à un moment donné.

Ce que j’aimerais faire, c’est que chaque instance de ce second formulaire écoute le gestionnaire d’événements du formulaire principal et mette à jour les contrôles de son instance du second formulaire.

Comment je ferais ça?

Voici un exemple de code. Je veux des informations du gestionnaire d’événements the_timer_Tick pour mettre à jour chaque instance de SecondaryForm.

public partial class Form1 : Form { Timer the_timer = new Timer(); public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { the_timer.Tick += new EventHandler(the_timer_Tick); the_timer.Interval = 2000; the_timer.Enabled = true; } 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"); } private void stop_timer_button_Click(object sender, EventArgs e) { the_timer.Enabled = false; } private void start_form_button_Click(object sender, EventArgs e) { SecondaryForm new_form = new SecondaryForm(); new_form.Show(); } } 

 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 } 

Pensez à utiliser des événements faiblement couplés. Cela vous permettra de coupler les classes de manière à ce qu’elles ne soient jamais directement conscientes les unes des autres. Le bloc d’application Unity est livré avec une extension appelée EventBroker qui rend cela très simple.

Voici un petit coup de sucre:

 public static class EVENTS { public const ssortingng 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 } } 

Maintenant, si vous construisez ces deux classes en utilisant Unity, elles seront automatiquement connectées ensemble.

Mettre à jour

Les solutions les plus récentes utilisent le bus de messages pour gérer les événements faiblement couplés. Voir http://masstransit-project.com/ ou http://nimbusapi.github.io/ à titre d’exemples.

Je suppose que vous pouvez faire en sorte que SecondaryForm prenne la forme parent dans le constructeur et ajoute un gestionnaire d’événements dans le constructeur.

 private void start_form_button_Click(object sender, EventArgs e) { SecondaryForm new_form = new SecondaryForm(this); new_form.Show(); } 

Dans SecondaryForm.cs:

 public SecondaryForm(ISomeView parentView) { parentView.SomeEvent += ..... }