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

StackOverflow https://stackoverflow.com/questions/610313

Question

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 apportées aux divers contrôles du formulaire principal. Cela fonctionne bien.

J'ai également 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 deuxième formulaire écoute le gestionnaire d'événements du formulaire principal et mette à jour les contrôles de son instance du deuxième formulaire.

Comment ferais-je cela?

Voici un exemple de code. Je souhaite utiliser les informations du gestionnaire d’événements_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();
    }
}
Était-ce utile?

La solution

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
  }

Autres conseils

Envisagez d'utiliser des événements à couplage lâche. 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 fourni avec une extension appelée EventBroker , ce qui rend cela très utile. simple.

Voici un petit coup de sucre:

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

Maintenant, si vous construisez ces deux classes avec 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 à couplage lâche. 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 l'ajout d'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 += .....
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top