Wrox Programmer Forums
|
VS.NET 2002/2003 Discussions about the Visual Studio.NET programming environment, the 2002 (1.0) and 2003 (1.1). ** Please don't post code questions here ** For issues specific to a particular language in .NET, please see the other forum categories.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the VS.NET 2002/2003 section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old January 6th, 2004, 05:03 PM
Authorized User
 
Join Date: Jun 2003
Posts: 16
Thanks: 0
Thanked 0 Times in 0 Posts
Default Reflection Events

Hello there, I need some help. I have a class that has a delegated event on it, but I call the class via Reflection. When I call a method this event is raised. How can I add a EventHandler to the reflected event?


Here is the code for the DLL I am trying to reflect.

Code:
Imports System
Imports System.Reflection


Public Delegate Sub ADelegate(ByVal sender As Object, ByVal Status As String)

Public Class TestEventDLL
    Public Event OnADelegate As ADelegate

    Public Function RaiseEvnt() As String
        RaiseEvent OnADelegate(Me, "TEST")

        Return "CompletedFunction"
    End Function
End Class
Here's the code of the form calling the DLL I am trying to reflect.

Now you will have to make a change to the file location to match where you built the dll.

Code:
Imports System.Reflection

Public Class Form1
    Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    Friend WithEvents Button1 As System.Windows.Forms.Button
    Friend WithEvents Button2 As System.Windows.Forms.Button
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.Button1 = New System.Windows.Forms.Button
        Me.Button2 = New System.Windows.Forms.Button
        Me.SuspendLayout()
        '
        'Button1
        '
        Me.Button1.Location = New System.Drawing.Point(4, 6)
        Me.Button1.Name = "Button1"
        Me.Button1.TabIndex = 0
        Me.Button1.Text = "Reflection"
        '
        'Button2
        '
        Me.Button2.Location = New System.Drawing.Point(82, 6)
        Me.Button2.Name = "Button2"
        Me.Button2.TabIndex = 1
        Me.Button2.Text = "Direct"
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(292, 266)
        Me.Controls.Add(Me.Button2)
        Me.Controls.Add(Me.Button1)
        Me.Name = "Form1"
        Me.Text = "Form1"
        Me.ResumeLayout(False)

    End Sub

#End Region
    Private Delegate Sub myDelegate(ByVal sender As Object, ByVal Status As String)

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim myAssembly As System.Reflection.Assembly
        Dim myType As System.Type
        Dim myObject As Object
        Dim myMethod As System.Reflection.MethodInfo
        Dim myEvent As System.Reflection.EventInfo

        myAssembly = System.Reflection.Assembly.LoadFrom("Y:\VBNET\TestEventDll\bin\TestEventDll.dll")
        myType = myAssembly.GetType("TestEventDll.TestEventDLL")
        myObject = Activator.CreateInstance(myType)

        myMethod = myObject.GetType().GetMethod("RaiseEvnt")
        'I DON'T KNOW WHAT TO DO HERE TO ADD A HANDLER
        myObject.GetType.GetEvent("OnADelegate").AddEventHandler(myObject, New myDelegate(AddressOf HandleADelegate))
        MessageBox.Show(myMethod.Invoke(myObject, Nothing))
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dim myAssembly As TestEventDll.TestEventDLL

        myAssembly = New TestEventDll.TestEventDLL
        AddHandler myAssembly.OnADelegate, AddressOf Me.HandleADelegate
        MessageBox.Show(myAssembly.RaiseEvnt())
    End Sub

    Private Sub HandleADelegate(ByVal sender As Object, ByVal Status As String)
        Me.Text = Status
    End Sub

End Class
As you can see with the direct call I can assign a local function to handle the event. I can't figure out how to do this via reflection. Is it possible? It should be because I can get the event info. Anyone who can help me it would be greatly appreciated.

Coop


It's important for us to explain to our nation that life is important. It's not only life of babies, but it's life of children living in, you know, the dark dungeons of the Internet."— George W. Bush - Arlington Heights, Ill., Oct. 24, 2000
__________________
Vote Kerry/Edwards 2004

It\'s important for us to explain to our nation that life is important. It\'s not only life of babies, but it\'s life of children living in, you know, the dark dungeons of the Internet.\"— George W. Bush - Arlington Heights, Ill., Oct. 24, 2000
 
Old October 8th, 2004, 04:07 PM
Registered User
 
Join Date: Oct 2004
Posts: 6
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Hello,

Did you figure this out? With late binding, how to I create an event handler? Note this is all VB.NET, even the assembly.class that I'm trying to late bind. If you know please give me some advice.

Code example:

Dim objDll As [Assembly]

objDll = [Assembly].LoadFrom("D:\My Documents\myassembly.dll")

Dim myType As Type = objDll.GetType("myassembly.myclass")

Dim obj As Object
obj = Activator.CreateInstance(mytype)

'now how do I achieve the following?
'myclass has an event called 'Helloworld'

' this does not work as obj has no
' event named helloworld???
addhandler obj.Helloworld, addressof me.myclassHelloworld

sub myclasshelloworld()
'code...
end sub





Thanks,

Glenn Romaniuk


 
Old October 18th, 2004, 01:25 PM
Authorized User
 
Join Date: Jun 2003
Posts: 16
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Glenn,

I figured it out... here is the updated form code.

Imports System.Reflection

Public Class Form1
    Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.
    'Do not modify it using the code editor.
    Friend WithEvents Button1 As System.Windows.Forms.Button
    Friend WithEvents Button2 As System.Windows.Forms.Button
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.Button1 = New System.Windows.Forms.Button
        Me.Button2 = New System.Windows.Forms.Button
        Me.SuspendLayout()
        '
        'Button1
        '
        Me.Button1.Location = New System.Drawing.Point(4, 6)
        Me.Button1.Name = "Button1"
        Me.Button1.TabIndex = 0
        Me.Button1.Text = "Reflection"
        '
        'Button2
        '
        Me.Button2.Location = New System.Drawing.Point(82, 6)
        Me.Button2.Name = "Button2"
        Me.Button2.TabIndex = 1
        Me.Button2.Text = "Direct"
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(292, 266)
        Me.Controls.Add(Me.Button2)
        Me.Controls.Add(Me.Button1)
        Me.Name = "Form1"
        Me.Text = "Form1"
        Me.ResumeLayout(False)

    End Sub

#End Region
    Private Delegate Sub myDelegate(ByVal sender As Object, ByVal Status As String)

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim myAssembly As System.Reflection.Assembly
        Dim myType As System.Type
        Dim myObject As Object
        Dim myMethod As System.Reflection.MethodInfo
        Dim myEvent As System.Reflection.EventInfo

        myAssembly = System.Reflection.Assembly.LoadFrom("C:\Documents and Settings\ccooper\My Documents\Visual Studio Projects\TestEventDLL\bin\TestEventDLL.dll")
        myType = myAssembly.GetType("TestEventDLL.TestEventDLL")
        myObject = Activator.CreateInstance(myType)

        myEvent = myObject.GetType().GetEvent("OnADelegate")
        myEvent.AddEventHandler(myObject, System.Delegate.CreateDelegate(myEvent.EventHandle rType, Me, "HandleADelegate"))
        myMethod = myObject.GetType().GetMethod("RaiseEvnt")

        myMethod.Invoke(myObject, Nothing)
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        'Dim myAssembly As TestEventDll.TestEventDLL

        'myAssembly = New TestEventDll.TestEventDLL
        'AddHandler myAssembly.OnADelegate, AddressOf Me.HandleADelegate
        'MessageBox.Show(myAssembly.RaiseEvnt())
    End Sub

    Private Sub HandleADelegate(ByVal sender As Object, ByVal Status As String)
        Me.Text = Status
    End Sub

End Class

Here is another example in C#

namespace ReflectionEventsRaised
{
    public delegate void RaiseEvent(object sender, object e);

    public interface IClassReflectionEventsRaised
    {
        event RaiseEvent onRaiseEvent;
    }
    /// <summary>
    /// Reflection Raised Event Class.
    /// </summary>
    public class ClassReflectionEventsRaised : IClassReflectionEventsRaised
    {
        #region Events
        public event ReflectionEventsRaised.RaiseEvent onRaiseEvent;
        #endregion
        #region ClassReflectionEventsRaised
        /// <summary>
        /// Constructor
        /// </summary>
        public ClassReflectionEventsRaised()
        {
        }
        #endregion
        #region RaiseMyEvent
        public void RaiseMyEvent(string status, string message)
        {
            this.ThrowOnRaiseEvent(status,message);
        }
        #endregion
        #region ThrowOnRaiseEvent
        private void ThrowOnRaiseEvent(string status, string message)
        {
            if (!(onRaiseEvent == null))
                this.onRaiseEvent(this, new RefectionEventArgs(status,message));
        }
        #endregion
    }

/// <summary>
    /// Summary description for RefectionEventArgs.
    /// </summary>
    public class RefectionEventArgs : EventArgs
    {
        #region Constructor
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="status">Status</param>
        /// <param name="message">Message</param>
        public RefectionEventArgs(string status, string message)
        {
            this.Status = status;
            this.Message = message;
        }
        #endregion
        #region Message
        /// <summary>
        /// Local variable used to store the value of the public property Message.
        /// </summary>
        private string message = System.String.Empty;
        /// <summary>
        /// Get or Set Message value.
        /// </summary>
        public string Message
        {
            get
            {
                return this.message;
            }
            set
            {
                this.message = value;
            }
        }
        #endregion
        #region Status
        /// <summary>
        /// Local variable used to store the value of the public property Status.
        /// </summary>
        private string status = System.String.Empty;
        /// <summary>
        /// Get or Set Status value.
        /// </summary>
        public string Status
        {
            get
            {
                return this.status;
            }
            set
            {
                this.status = value;
            }
        }
        #endregion
    }
}

Here is the calling form

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Reflection;
using System.Diagnostics;

namespace CatchReflectedEvents
{

    /// <summary>
    /// Summary description for Form1.
    /// </summary>
    public class Form1 : System.Windows.Forms.Form
    {
        private System.Windows.Forms.Button button1;
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.Container components = null;

        public Form1()
        {
            //
            // Required for Windows Form Designer support
            //
            InitializeComponent();
        }

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }

        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.button1 = new System.Windows.Forms.Button();
            this.SuspendLayout();
            //
            // button1
            //
            this.button1.Location = new System.Drawing.Point(4, 4);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(282, 23);
            this.button1.TabIndex = 0;
            this.button1.Text = "button1";
            this.button1.Click += new System.EventHandler(this.button1_Click);
            //
            // Form1
            //
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(292, 32);
            this.Controls.Add(this.button1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);

        }
        #endregion

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.Run(new Form1());
        }

        private void button1_Click(object sender, System.EventArgs e)
        {
            System.Reflection.Assembly myAssembly = null;
            System.Type myType = null;
            object myObject = null;;
            System.Reflection.MethodInfo myMethod = null;
            System.Reflection.EventInfo myEvent = null;

            object [] myParams = new object [2] {"Testing", "This is a test"};

            myAssembly = System.Reflection.Assembly.LoadFrom(@"C:\Documents and Settings\ccooper\My Documents\Visual Studio Projects\ReflectionEventsRaised\bin\Debug\Reflecti onEventsRaised.dll");
            myType = myAssembly.GetType("ReflectionEventsRaised.ClassRe flectionEventsRaised");
            myObject = Activator.CreateInstance(myType);

            myEvent = myObject.GetType().GetEvent("onRaiseEvent");
            myEvent.AddEventHandler(myObject, System.Delegate.CreateDelegate(myEvent.EventHandle rType, this, "OnHandleRaiseEvent"));
            myMethod = myObject.GetType().GetMethod("RaiseMyEvent");

            try
            {
                myMethod.Invoke(myObject, myParams);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }

        private void OnHandleRaiseEvent(object sender, object e)
        {
            System.Type myType = e.GetType();

            System.Reflection.PropertyInfo status = myType.GetProperty("Status");
            System.Reflection.PropertyInfo message = myType.GetProperty("Message");

            MessageBox.Show("Status : " + status.GetValue(e,null).ToString() + "\r\n" + "Message : " + message.GetValue(e,null).ToString());
        }
    }
}



Vote Kerry/Edwards 2004

It's important for us to explain to our nation that life is important. It's not only life of babies, but it's life of children living in, you know, the dark dungeons of the Internet."— George W. Bush - Arlington Heights, Ill., Oct. 24, 2000
 
Old September 8th, 2005, 10:05 PM
Registered User
 
Join Date: Sep 2005
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via Yahoo to eros
Default

Anyone here expert to use AddEventHandler or other way to solve this small problem of mine because I am a student that developing my thesis.

Situation: I have a form (frm) and a textbox (txt) on the frm and a seperate .vb file Class (cls) and a procedure (txtKeyUp) intended to handle the frm.txt.KeyUp event.

Problem: I'm not allowed to code in frm only in the cls.

Code Sample:

frm.vb

Public Class frm
    Inherits System.Windows.Forms.Form
''''''''''Generated Code
+ Windows "........."

End Class


cls.vb

Public Class cls

    Public Sub New()
    ''''''''''Implementation Code here
    'If im not mistaken must be here the required code in order to
    'Handle the frm.txt.KeyUp event.
    'something AddEventHandler here.
    End Sub

    Public Sub txtKeyUp()
    ''''''''''Implementation Code here
    End Sub
End Class

Eros Sy
Philippines
 
Old September 8th, 2005, 10:06 PM
Registered User
 
Join Date: Sep 2005
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via Yahoo to eros
Default

Anyone here expert to use AddEventHandler or other way to solve this small problem of mine because I am a student that developing my thesis.

Situation: I have a form (frm) and a textbox (txt) on the frm and a seperate .vb file Class (cls) and a procedure (txtKeyUp) intended to handle the frm.txt.KeyUp event.

Problem: I'm not allowed to code in frm only in the cls.

Code Sample:

frm.vb

Public Class frm
    Inherits System.Windows.Forms.Form
''''''''''Generated Code
+ Windows "........."

End Class



cls.vb

Public Class cls

    Public Sub New()
    ''''''''''Implementation Code here
    'If im not mistaken must be here the required code in order to
    'Handle the frm.txt.KeyUp event.
    'something AddEventHandler here.
    End Sub

    Public Sub txtKeyUp()
    ''''''''''Implementation Code here
    End Sub
End Class

Eros Sy
Philippines





Similar Threads
Thread Thread Starter Forum Replies Last Post
Reflection-TargetInvocationException dipak_2111 C# 2005 0 January 11th, 2007 01:08 AM
Reflection jayakumar.cj ASP.NET 1.0 and 1.1 Basics 1 July 15th, 2006 06:12 AM
Reflection and WebControl jdang67 ASP.NET 2.0 Professional 1 October 20th, 2005 04:14 PM
Attributes and Reflection eadred General .NET 0 July 22nd, 2005 01:53 AM
Reflection ffbalota C# 2 January 8th, 2004 03:07 PM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.