2010-04-21 4 views
0

je les classes suivantes:VB.NET: WithEvents ne fonctionne pas

Public Class Email 

    Private Shared ReadOnly EMAIL_REGEX = "\b[a-zA-Z]+[a-zA-Z0-9._+-][email protected]" + _ 
             "[a-zA-Z0-9.-]+\.[a-zA-Z]{2,3}\b" 
    Private _email As String 

    Public Event emailCreated() 

    ' Declare empty constructor private so the only way to create an object 
    ' is using new (email) 
    Private Sub New() 

    End Sub 

    Sub New(ByVal email As String) 
     If Regex.IsMatch(email, EMAIL_REGEX) Then 
      _email = email 
      RaiseEvent emailCreated() 
     Else 
      Throw New Exception("Email Not Valid") 
     End If 
    End Sub 

    ReadOnly Property Email() As String 
     Get 
      Return _email 
     End Get 
    End Property 

End Class 

Et

Public Class EmailForm 

    WithEvents myEmail As Email 

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 
     Try 
      myEmail = New Email(TextBox1.Text) 
     Catch ex As Exception 
      MessageBox.Show("Exception: " & ex.Message) 
     End Try 
    End Sub 

    Public Sub emailCreated() Handles myEmail.emailCreated 
     MessageBox.Show("New Email Created") 
    End Sub 

End Class 

Si créer un e-mail erronée permet de dire "email" l'exception est correctement mis en mémoire cache et un message est montré cependant je saisis un email valide l'événement n'est pas levé, l'objet est créé mais aucun message n'est montré et aucune erreur ou exception n'est levée je suspecte qu'il a quelque chose faire avec using "myemail = nouvel email (email)" mais j'ai vu des exemples d'utilisation de nouveau avec withevents sans problème. J'aprécier toute entrée sur ce problème

merci

Edit: pour référence future - VB.NET - problem with member's event handling

Répondre

3

Vous ne devez pas valider les adresses e-mail à l'aide des expressions régulières.

Vous devez utiliser la classe à la place MailAddress:

Sub New(ByVal email As String) 
    New MailAddress(email).ToString() 
End Sub 

La classe MailAddress utilise un analyseur BNF pour valider l'adresse et jetteront un FormatException si l'adresse est invalide.

Votre adresse regex rejettera les adresses valides comme [email protected].


Pour répondre à votre question, l'événement est soulevée devant le champ WithEvents a une valeur.

Voici ce qui se passe lorsque votre code est exécuté:

  1. New Email(TextBox1.Text) - L'objet Email est créé, et le constructeur déclenche l'événement.
    A ce stade, l'événement n'a aucun gestionnaire, donc l'événement ne fait rien.
  2. myEmail = ... Le nouvel objet Email est affecté au champ myEmail et le gestionnaire d'événements est ajouté.

Il n'est pas possible de contourner ce problème, car vous ne pouvez pas obtenir une référence à un objet avant la fin de son constructeur.

Au lieu de cela, vous devriez vous débarrasser de l'événement et rendre le champ myEmail dans une propriété avec votre code dans le setter de propriété

+0

Merci pour votre réponse Je n'étais pas au courant de la classe MailAddress mais cela ne résout pas le problème de l'événement. – Hei

+0

Je comprends maintenant, fondamentalement l'événement est soulevé avant qu'il puisse être manipulé, la solution évidente semble être soulevant l'événement en dehors du constructeur, est-il un moyen de le faire sans utiliser un processus en deux étapes comme "e = new email () e.Email = "[email protected]" "? – Hei

+0

Oui, mais vous ne devriez pas. Il serait beaucoup plus propre d'utiliser une propriété à la place. – SLaks

1

Première supposition: un email est créé avant les événements sont reliés à elle. Vous déclenchez l'événement avant même que vous ne soyez sorti du constructeur, avant même que VB ait la possibilité d'ajouter des gestionnaires d'événements, de sorte que l'événement ne sera jamais vu.

Vue agrandie. Y a-t-il une raison particulière pour laquelle vous voulez qu'un événement emailCreated soit déclenché? Il semble que l'événement ne sera jamais traité en dehors de votre propre classe, même si vous finissez par le faire fonctionner, donc l'utilisation d'événements ajoute de la complexité dont vous n'avez pas besoin ou même que vous ne voulez pas.

+0

@cHao Bonjour Merci pour votre réponse, l'idée est de rendre le constructeur la seule façon pour créer un email valide si je crée un setter alors quelqu'un pourrait utiliser le même objet d'email plusieurs fois s'il y avait un moyen d'éviter cela? peut-être rendre le _email readonly. – Hei

+1

Vous n'avez pas besoin d'événements pour cela - en fait, c'est probablement l'utilisation la plus étrange que j'ai vu pour eux. Quel est le problème avec juste avoir les propriétés en lecture seule, et en définissant tout ce dont vous avez besoin dans le constructeur, et en lançant une exception si quelque chose ne va pas? Ensuite, si vous avez un email, vous savez que c'est valide. – cHao

+0

Ce serait la situation idéale, je voulais juste en savoir plus sur les événements. Mais oui je suis d'accord avec toi – Hei