10
votes

Comment appeler manuellement un événement en C #?

J'ai une usercontroll dans laquelle j'ai une zone de texte. J'utilise le UserControl de ma forme, je veux faire quelque chose lorsque quelqu'un appuie sur la zone de texte. Comment puis-je le faire? Si vous me dites comment appeler manuellement un événement, je peux appeler usercontrol.keydown dans textbox.keydown.


4 commentaires

Vous voulez donc élever l'événement USERCONTROL.KEDOOD à partir du gestionnaire d'événements Textbox.KeyDown à connaître, est-ce correct?


Donc, répondez à l'événement lorsque l'utilisateur appuie réellement une clé ne suffit pas pour votre scénario? Je pense que je manque quelque chose dans votre scénario.


@Saeed - En principe, les solutions sont les mêmes, mais cela est-ce pour ASP.NET ou WinForms?


@RQDQ: Je n'ai pas compris ce que vous avez manqué.


6 Réponses :


13
votes

Premièrement, les événements ne peuvent être soulevés que du code dans le contrôle qui déclare l'événement. Donc, votre contrôle de l'utilisateur doit déclarer la clé d'événement personnalisée afin de l'augmenter. Vous ne pouvez pas, par exemple, soulever la clé sur une zone de texte contenue par votre contrôle utilisateur. Cependant, vous pouvez déclarer votre propre clé et joindre un gestionnaire à la clé de la zone de texte qui augmentera votre propre clé.

Compte tenu de cette restriction, la levée d'un événement est facile: P>

public delegate void MyEventHandler(object sender, MyEventArgs e)

public event MyEventHandler MyEvent;

public void RaisesMyEvent()
{
   ...

   if(MyEvent != null) //required in C# to ensure a handler is attached
      MyEvent(this, new MyEventArgs(/*any info you want handlers to have*/));
}


6 commentaires

Malheureusement, ce code n'est pas le fil sûr. Vous devez créer une copie locale de myEvent pour sauvegarder contre NullReferenceExceptions résultant lorsqu'un autre fil supprime simultanément tous les gestionnaires d'événements entre votre si et le Invocation d'événement.


... ou verrouillage (myevent ()) avant d'évaluer le si, et de la libérer après. La question était simplement de soulever un événement et c'est ce que j'ai répondu; S'il attache et détacher des gestionnaires Willy-Nilly, cela indique une connaissance plus avancée des événements en général, empêchant la nécessité de poser la question.


Vous avez raison en principe mais ce n'est pas ce que je veux dire: la copie de l'événement localement est une meilleure pratique bien établie. NO Le code de collecte d'événements ne doit jamais être écrit sans cela, pas même comme un exemple (comme si vous ne vous attendez pas à la question de multithreading, vous ne le penserez pas). Fixation d'événements NILLY-WILLY n'est pas quelque chose que le code du contrôle de l'utilisateur peut contrôler - il appartient à l'utilisateur. En tant que code réutilisable, le code de contrôle de l'utilisateur doit être aussi robuste que possible.


Hmya, c'est le dogme mais à peine pertinent ici. Un contrôle comporte seulement 4 membres qui sont documentés pour être utilisables d'un autre fil (invoquentiel, etc.). Même MSFT ne le fait pas de manière cohérente, NumericupDown par exemple.


Mais aucun délégué de multidiffusion n'a de plusieurs délégués qui y sont attachés? Alors, comment un événement est-il différent?


Dans la version récente de .NET, le test peut être plié dans l'invocation avec cette syntaxe: myEvent? .Invoke (param1, param2, etc.) Je n'ai pas vérifié les docs mais je suppose que c'est le fil de sécurité (Depuis vraisemblablement que c'est le point)



0
votes

Ce que vous décrivez est appelé événement bouillonnant. Voici un exemple:

public partial class MyPage : Page {
 protected void ucMyUserControl_UserControlTextBoxChanged(object sender, EventArgs e) {
  // sender is ucMyUserControl.TextBox1
 }
}


1 commentaires

Juste pour clarifier car j'ai peut-être mal compris la question. Vous recherchez spécifiquement 'Entrée' spécifiquement ou essayez-vous de capturer une soumission via la zone de texte?



1
votes

Typiquement, l'invocation de l'événement est enveloppée dans une méthode nommée quelque chose comme "ON [EventName]" qui valide que le Delgate a une ou plusieurs cibles (événement n'est pas null), puis l'invoque avec l'expéditeur et les arguments applicables ... alors quelque chose comme ceci est le modèle typique: xxx

tout ce qui doit soulever cet événement invoque cette méthode (en supposant que c'est accessible).

Si vous voulez simplement Pour réussir l'événement, alors comme UserControl, vous pouvez probablement simplement appeler la base "sur la méthode [événement]", qui est probablement exposée. Vous pouvez également câbler les gestionnaires d'événements, pour passer directement l'événement d'un contrôle des enfants comme étant l'événement de la commande parent ... de sorte que TXTfoo.KeyPress appelle simplement la méthode OnKeyPress de la commande parent.


0 commentaires

0
votes

Si vous utilisez WPF, vous pourrez peut-être utiliser RAESEEEvent: http://msdn.microsoft.com/en-us/library/system.windows.uielement.raiseevent.aspx

Mais c'est faux pour ce que vous voulez faire. P >

Vous devez baisser l'événement. P>

class MyControl : UserControl {
    public KeyDownEventHandler KeyDown;

    private void OnTextBoxKeyDown(object sender, EventArgs e){ KeyDown.Invoke(sender, e); }
}


0 commentaires

3
votes

Je cherchais une réponse à ce problème pour moi,

juste faire cela p>

Examble: P>

//this is the call to trigger the event:

 **lst_ListaDirectorios_SelectedIndexChanged(this, new EventArgs());**

//do that if you have the method signature in the same class as I do. (something like this below)
private void lst_ListaDirectorios_SelectedIndexChanged(object sender, EventArgs e)
        {
          //do something
         }


0 commentaires

-1
votes

Si vous avez vraiment besoin d'appeler un événement manuellement, vous pouvez obtenir le délégué du support, qui est généralement privé. Utilisez un .NET Decompiler (telle que ILSPY) pour localiser le champ de support de l'événement, utilisez la réflexion pour obtenir le délégué de soutien.

Exemple: Obtenir l'événement Dowork à partir de Backworker : Code> Events Membre et le champ DoworkKey en tant que clé.

Events est un EventHandlerList ( Classe publique) Déclaré en classe composant .

doworkkey est un champ statique déclaré dans la classe Backworker . .

Utilisez ensuite la réflexion pour obtenir le délégué: xxx

Vous avez maintenant un délégué pour l'événement dowork et peut l'appeler.

Cette même approche fonctionnera également pour d'autres commandes.

Notez que l'utilisation de la réflexion pour obtenir des champs privés peut casser à tout moment une nouvelle version du code. >


0 commentaires