web-dev-qa-db-fra.com

Comment ajouter un événement à un UserControl en C #?

J'ai un UserControl qui contient 3 étiquettes. Je veux ajouter un événement pour cela, ce qui se produit lorsque le texte d'une des étiquettes a changé.
J'utilise Visual Studio 2010

24
Saeed

Tout d’abord, vous devez déclarer l’événement dans votre classe (à côté de vos méthodes et constructeurs):

public event EventHandler LabelsTextChanged;

Ensuite, vous devez créer une méthode pour gérer les événements TextChanged des étiquettes individuelles.

private void HandleLabelTextChanged(object sender, EventArgs e)
{
    // we'll explain this in a minute
    this.OnLabelsTextChanged(EventArgs.Empty);
}

Quelque part, probablement dans le constructeur de votre contrôle, vous devez vous abonner aux événements TextChanged de l'étiquette.

myLabel1.TextChanged += this.HandleLabelTextChanged;
myLabel2.TextChanged += this.HandleLabelTextChanged;
myLabel3.TextChanged += this.HandleLabelTextChanged;

Passons maintenant à la méthode HandleLabelsTextChanged. Nous pourrions élever LabelsTextChanged directement; Cependant, selon les directives de conception du framework .NET, il est recommandé de créer une méthode virtuelle protégée OnEventName afin de générer l'événement pour nous. De cette manière, les classes héritées peuvent "gérer" l'événement en surchargeant la méthode OnEventName, ce qui s'avère être un peu plus performant que l'abonnement à l'événement. Même si vous pensez ne jamais remplacer la méthode OnEventName, il est judicieux de prendre l'habitude de le faire, car cela simplifie le processus de génération d'événement.

Voici notre OnLabelsTextChanged:

protected virtual void OnLabelsTextChanged(EventArgs e)
{
    EventHandler handler = this.LabelsTextChanged;
    if (handler != null)
    {
        handler(this, e);
    }
}

Nous devons vérifier la valeur null car un événement sans abonnés est null. Si nous essayions de générer un événement null, nous aurions une NullReferenceException. Notez que nous copions la variable EventHandler de l'événement dans une variable locale avant de rechercher la valeur null et de déclencher l'événement. Si nous l'avions plutôt fait comme ceci:

if (this.LabelsTextChanged != null)
{
    this.LabelsTextChanged(this, e);
}

Nous aurions une condition de concurrence entre le contrôle de nullité et le relèvement de l'événement. S'il arrivait que les abonnés à l'événement se désabonnent eux-mêmes juste avant de déclencher l'événement, mais après avoir vérifié la valeur null, une exception serait levée. Vous ne rencontrerez normalement pas ce problème, mais il est préférable de prendre l'habitude de l'écrire de manière sécurisée.

Edit: Voici comment la ligne public event EventHandler LabelsTextChanged; devrait être placée:

namespace YourNamespace
{
    class MyUserControl : UserControl
    {
        // it needs to be here:
        public event EventHandler LabelsTextChanged;

        ...
    }
}

Ici sont les lignes directrices de conception de cadre sur la conception d'événements à lire davantage.

51
Zach Johnson

Vous devez d’abord déclarer un événement dans votre contrôle utilisateur, par exemple:

public event EventHandler TextOfLabelChanged;

vous devez ensuite appeler la fonction de rappel liée à votre événement (s'il y en a un) au moment de l'exécution. Vous pouvez le faire en gérant l'événement TextChanged d'une étiquette comme celle-ci:

public void LabelTextChanged(object sender,EventArgs e)
{
if(TextOfLabelChanged!=null)
TextOfLabelChanged(sender,e);
}

Vous pouvez avoir votre propre objet EventArgs si vous le souhaitez.

quelque part dans votre code, vous devez lier votre événement TextChanged à cette méthode comme ceci:

_myLabel.TextChanged+=LabelTextChanged;
3
Beatles1692

erreur de compilation, qui dit: "Classe, délégué, enum, interface ou struct attendu" sur la deuxième ligne, il semble y avoir un problème avec "événement ...


Ces 2 lignes doivent être DANS la déclaration de classe.

public delegate void TextChangedEventHandler(object sender, EventArgs e);
public event TextChangedEventHandler LabelTextChanged;
1
Vince

Il y a un moyen très simple de faire ça!

Sur le formulaire UserControl:

  1. changer les propriétés en public pour accéder partout

sur le formulaire principal, où vous utilisez UserControl:

.5: dans la région using ajouter using userControl1=UserControl.userControl1

1.Ajouter l'événement 'Laod' à votre UserControl:

this.userControl1.Load += new System.EventHandler(this.userControl1_Load);

2.Dans le userControl1_Load:

private void userControl1_Load(object sender, EventArgs e)
{
     (sender as UserControl1).label1.TextChanged += label1_TextChanged; 
     //add a 'TextChanged' event to the label1 of UserControl1 
     OR use direct cast:
     ((UserControl1) sender).label1.TextChanged += label1_TextChanged;

}

3.Dans le label1_TextChanged:

 private void label1_TextChanged(object sender, EventArgs e)
 {
     //do whatever you want
 }
1
Arsalan

Vous devez déclarer les event et delegate dans Namespace. Essayez d’intégrer le code dans la portée class. Cela fonctionnera bien.

0
prem
public delegate void TextChangedEventHandler(object sender, EventArgs e);
public event TextChangedEventHandler LabelTextChanged;

// ...

protected void MyTextBox_TextChanged(object sender, EventArgs e)
{
    if (LabelTextChanged != null) {
        LabelTextChanged(this, e);
    }
}
0
thelost