Maison >développement back-end >C++ >Les gestionnaires d'événements peuvent-ils être transférés par programme entre les contrôles dans les formulaires Windows ?

Les gestionnaires d'événements peuvent-ils être transférés par programme entre les contrôles dans les formulaires Windows ?

Linda Hamilton
Linda Hamiltonoriginal
2025-01-04 19:04:40342parcourir

Can Event Handlers Be Programmatically Transferred Between Controls in Windows Forms?

Les gestionnaires d'événements peuvent-ils être transférés entre les contrôles ?

La possibilité de « voler » un gestionnaire d'événements d'un contrôle et de l'attribuer à un autre a est un sujet de débat dans la communauté de la programmation depuis des années. Bien que la syntaxe suggérée dans la question ne soit pas valide, il est en effet techniquement possible de transférer des gestionnaires d'événements entre les contrôles au moment de l'exécution.

La route de réflexion

En raison de la propriété privée et nature interne de certains membres au sein du framework Windows Forms, une réflexion est nécessaire pour accomplir cette prouesse. En tirant parti de la réflexion, vous pouvez accéder à des champs et propriétés privés qui seraient autrement inaccessibles.

Dans l'exemple de code fourni, une série d'opérations de réflexion sont effectuées :

  • L'événement de clic secret key est récupéré de la classe Control.
  • L'événement click est récupéré de la classe Component.
  • Le gestionnaire d'événements pour bouton1 est supprimé, puis ajouté au bouton2.

Cela transfère efficacement le gestionnaire d'événements du bouton1 au bouton2.

Exemple d'implémentation

Voici une version révisée du code fourni dans le question :

using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Reflection;

namespace EventHandlerTransfer {
  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
      button1.Click += new EventHandler(button1_Click);
      TransferEventHandler(button1, button2);
    }

    private void TransferEventHandler(Control source, Control destination) {
      // Get secret click event key
      FieldInfo eventClick = typeof(Control).GetField("EventClick", BindingFlags.NonPublic | BindingFlags.Static);
      object secret = eventClick.GetValue(null);
      // Retrieve the click event
      PropertyInfo eventsProp = typeof(Component).GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance);
      EventHandlerList eventsSource = (EventHandlerList)eventsProp.GetValue(source, null);
      EventHandlerList eventsDestination = (EventHandlerList)eventsProp.GetValue(destination, null);
      Delegate click = eventsSource[secret];
      // Remove it from source, add it to destination
      eventsSource.RemoveHandler(secret, click);
      eventsDestination.AddHandler(secret, click);
    }

    void button1_Click(object sender, EventArgs e) {
      MessageBox.Show("Yada");
    }
  }
}

Conclusion

Bien que la possibilité de transférer des gestionnaires d'événements de cette manière puisse sembler une fonctionnalité puissante, elle doit être utilisée avec prudence. Cette technique repose fortement sur la réflexion, ce qui peut avoir des implications sur les performances et peut également introduire des bogues potentiels. De plus, la modification des membres privés du framework Windows Forms n'est pas recommandée car cela pourrait interrompre votre application en cas de modifications dans les futures versions du framework.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn