Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Piéger les événements d'un objet instancié dynamiquement

3 réponses
Avatar
Gus
bonjour,
en VB.NET 2003, j'instancie dynamiquement un objet qui lève un événement et
je cherche à piéger cet événement dans la procédure principale, mais
j'obtiens une erreur de compilation :

'instancie dynamiquement "MyAssembly.MyObject"
Dim asm As [Assembly] = [Assembly].Load("MyAssembly")
Dim typ As Type = asm.GetType("MyAssembly.MyObject")
Dim obj As Object = Activator.CreateInstance(typ)

'ajoute un gestionnaire d'evenements
AddHandler obj.MyEvent, AddressOf MyProcEvent --> Erreur

Erreur = MyEvent n'est pas un événement de 'System.Object'

Comment traiter cet événement ?
Merci

3 réponses

Avatar
Zoury
Salut Gus ! :O)

Voici un exemple :
'***
' classe appelant l'autre assembly
Option Explicit On

Imports System.Reflection

Public Class Form1
Inherits System.Windows.Forms.Form

' code généré...

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

Dim a As [Assembly] = [Assembly].LoadFile("C:MyAssembly.dll")
Dim t As Type = a.GetType(String.Format("{0}.MyEventThrower",
a.GetName().Name))
Dim o As Object = Activator.CreateInstance(t)
Dim ev As EventInfo = t.GetEvent("MyEvent")
Dim handler As [Delegate] [Delegate].CreateDelegate(ev.EventHandlerType, Me, "MyEventHandler")

ev.AddEventHandler(o, handler)
t.InvokeMember("MyThrowEventSub", _
BindingFlags.Public Or _
BindingFlags.InvokeMethod Or _
BindingFlags.Instance, _
Nothing, o, Nothing)
ev.RemoveEventHandler(o, handler)

End Sub

Public Sub MyEventHandler(ByVal sender As Object, ByVal e As EventArgs)
Console.WriteLine("Yippie!")
End Sub

End Class
'***
' classe MyEventThrower
Public NotInheritable Class MyEventThrower

Public Event MyEvent As EventHandler

Public Sub MyThrowEventSub()

RaiseEvent MyEvent(Me, New EventArgs)

End Sub

End Class
'***


Maitenant ce que j'ai pas encore réussi à faire, c'est implémenter un
événement qui emploi une classe de paramètres propriétaire.. comme celle-ci
par exemple :
'***
Option Explicit On

Public Delegate Sub MyEventHandler(ByVal sender As Object, ByVal e As
MyEventArgs)

Public NotInheritable Class MyEventArgs
Inherits EventArgs

Private m_nValue As Int32

Public Property Value() As Int32
Get
Return m_nValue
End Get
Set(ByVal Value As Int32)
m_nValue = Value
End Set
End Property

End Class

Public NotInheritable Class MyEventThrower

Public Event MyEvent As MyEventHandler

Public Sub MyThrowEventSub()

Dim e As New MyEventArgs
RaiseEvent MyEvent(Me, e)
Console.WriteLine(e.Value)

End Sub

End Class
'***


J'obtiens toujours une erreur lorsque je tente de "m'abonner" à l'événement,
étant donnée que le classe MyEventArgs n'est pas définie dans le projet
appelant :
'***
Public Sub MyEventHandler(ByVal sender As Object, ByVal e As
MyEventArgs)
'***

J'ai aussi tenté de modifier la signature pour ceci mais sans succès pour
l'instant... :
'***
Public Sub MyEventHandler(ByVal sender As Object, ByVal e As EventArgs)
Public Sub MyEventHandler(ByVal sender As Object, ByVal e As Object)
'***

Alors si quelqu'un à une idée ... :O)

--
Cordialement
Yanick
MVP pour Visual Basic
"Gus" a écrit dans le message de
news:
bonjour,
en VB.NET 2003, j'instancie dynamiquement un objet qui lève un événement


et
je cherche à piéger cet événement dans la procédure principale, mais
j'obtiens une erreur de compilation :

'instancie dynamiquement "MyAssembly.MyObject"
Dim asm As [Assembly] = [Assembly].Load("MyAssembly")
Dim typ As Type = asm.GetType("MyAssembly.MyObject")
Dim obj As Object = Activator.CreateInstance(typ)

'ajoute un gestionnaire d'evenements
AddHandler obj.MyEvent, AddressOf MyProcEvent --> Erreur

Erreur = MyEvent n'est pas un événement de 'System.Object'

Comment traiter cet événement ?
Merci


Avatar
Gus
excellent, ça y est ça tourne !
j'ai quand même patogé un peu avec les formats de paramètres de l'événement
...
d'où "Erreur de liaison avec la méthode cible", tu connais ...
et du coup j'ai bien compris ton pb de classe de paramètres perso pour
l'événement

y a une solution (pas trop propre ...) = déclarer Object "des 2 côtés"

Public Delegate Sub MyEventHandler(ByVal sender As Object, ByVal e As
Object)
et
Public Sub MyEventHandler(ByVal sender As Object, ByVal e As Object)

merci pour ton aide, j'aurai cherché bien longtemps avec les délégués ...
et ça m'évite de casser mon architecture de classes !


"Zoury" a écrit :

Salut Gus ! :O)

Voici un exemple :
'***
' classe appelant l'autre assembly
Option Explicit On

Imports System.Reflection

Public Class Form1
Inherits System.Windows.Forms.Form

' code généré...

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

Dim a As [Assembly] = [Assembly].LoadFile("C:MyAssembly.dll")
Dim t As Type = a.GetType(String.Format("{0}.MyEventThrower",
a.GetName().Name))
Dim o As Object = Activator.CreateInstance(t)
Dim ev As EventInfo = t.GetEvent("MyEvent")
Dim handler As [Delegate] > [Delegate].CreateDelegate(ev.EventHandlerType, Me, "MyEventHandler")

ev.AddEventHandler(o, handler)
t.InvokeMember("MyThrowEventSub", _
BindingFlags.Public Or _
BindingFlags.InvokeMethod Or _
BindingFlags.Instance, _
Nothing, o, Nothing)
ev.RemoveEventHandler(o, handler)

End Sub

Public Sub MyEventHandler(ByVal sender As Object, ByVal e As EventArgs)
Console.WriteLine("Yippie!")
End Sub

End Class
'***
' classe MyEventThrower
Public NotInheritable Class MyEventThrower

Public Event MyEvent As EventHandler

Public Sub MyThrowEventSub()

RaiseEvent MyEvent(Me, New EventArgs)

End Sub

End Class
'***


Maitenant ce que j'ai pas encore réussi à faire, c'est implémenter un
événement qui emploi une classe de paramètres propriétaire.. comme celle-ci
par exemple :
'***
Option Explicit On

Public Delegate Sub MyEventHandler(ByVal sender As Object, ByVal e As
MyEventArgs)

Public NotInheritable Class MyEventArgs
Inherits EventArgs

Private m_nValue As Int32

Public Property Value() As Int32
Get
Return m_nValue
End Get
Set(ByVal Value As Int32)
m_nValue = Value
End Set
End Property

End Class

Public NotInheritable Class MyEventThrower

Public Event MyEvent As MyEventHandler

Public Sub MyThrowEventSub()

Dim e As New MyEventArgs
RaiseEvent MyEvent(Me, e)
Console.WriteLine(e.Value)

End Sub

End Class
'***


J'obtiens toujours une erreur lorsque je tente de "m'abonner" à l'événement,
étant donnée que le classe MyEventArgs n'est pas définie dans le projet
appelant :
'***
Public Sub MyEventHandler(ByVal sender As Object, ByVal e As
MyEventArgs)
'***

J'ai aussi tenté de modifier la signature pour ceci mais sans succès pour
l'instant... :
'***
Public Sub MyEventHandler(ByVal sender As Object, ByVal e As EventArgs)
Public Sub MyEventHandler(ByVal sender As Object, ByVal e As Object)
'***

Alors si quelqu'un à une idée ... :O)

--
Cordialement
Yanick
MVP pour Visual Basic
"Gus" a écrit dans le message de
news:
> bonjour,
> en VB.NET 2003, j'instancie dynamiquement un objet qui lève un événement
et
> je cherche à piéger cet événement dans la procédure principale, mais
> j'obtiens une erreur de compilation :
>
> 'instancie dynamiquement "MyAssembly.MyObject"
> Dim asm As [Assembly] = [Assembly].Load("MyAssembly")
> Dim typ As Type = asm.GetType("MyAssembly.MyObject")
> Dim obj As Object = Activator.CreateInstance(typ)
>
> 'ajoute un gestionnaire d'evenements
> AddHandler obj.MyEvent, AddressOf MyProcEvent --> Erreur
>
> Erreur = MyEvent n'est pas un événement de 'System.Object'
>
> Comment traiter cet événement ?
> Merci





Avatar
Zoury
Salut Gus ! :O)

y a une solution (pas trop propre ...) = déclarer Object "des 2 côtés"



Oui en effet ! bonne idée.
Personnlement, j'aurais plutôt opté pour "As EventArgs".. ;O)

Ex :
'***
Public Delegate Sub MyEventHandler(ByVal sender As Object, ByVal e As
EventArgs)

Public NotInheritable Class MyEventArgs
Inherits EventArgs

Private m_nValue As Int32

Public Property Value() As Int32
Get
Return m_nValue
End Get
Set(ByVal Value As Int32)
m_nValue = Value
End Set
End Property

End Class

Public NotInheritable Class MyEventThrower

Public Event MyEvent As MyEventHandler

Public Sub MyThrowEventSub()

Dim e As New MyEventArgs
RaiseEvent MyEvent(Me, e)
Console.WriteLine(e.Value)

End Sub

End Class
'***
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

Dim a As [Assembly] [Assembly].LoadFile("c:LoadAssemblyAndAddHandlerLibrary.dll")
Dim t As Type = a.GetType(String.Format("{0}.MyEventThrower",
a.GetName().Name))
Dim o As Object = Activator.CreateInstance(t)
Dim ev As EventInfo = t.GetEvent("MyEvent")
Dim handler As [Delegate] [Delegate].CreateDelegate(ev.EventHandlerType, Me, "MyEventHandler")

ev.AddEventHandler(o, handler)
t.InvokeMember("MyThrowEventSub", _
BindingFlags.Public Or _
BindingFlags.InvokeMethod Or _
BindingFlags.Instance, _
Nothing, o, Nothing)
ev.RemoveEventHandler(o, handler)

End Sub

Public Sub MyEventHandler(ByVal sender As Object, ByVal e As EventArgs)

Dim a As [Assembly] [Assembly].LoadFile("c:LoadAssemblyAndAddHandlerLibrary.dll")
Dim t As Type = a.GetType(String.Format("{0}.MyEventArgs",
a.GetName().Name))
Dim p As PropertyInfo = t.GetProperty("Value")
p.SetValue(e, 15, Nothing)

End Sub
'***

--
Cordialement
Yanick
MVP pour Visual Basic