Raising event via reflection using web forms with codebehind

I understand that there are a number of questions that involve raising an event through reflection, however I could not find an answer to the following [I suspect the answer is no]:

Given the "standard" event declaration, is there a way to raise the event by referencing a string literal.

For example, pseudocode:

Dim eventName As String = "TestEvent"
RaiseEvent eventName

      

Obviously this won't work.

I can get the type of event / multicast handler with

Me.GetType.GetEvent("TestEvent").GetAddMethod.GetParameters(0).Name
// "TestEventEventHandler

      

But I cannot find an instance of this page object to call .GetInvocationList

It is similar to this question: How can I get the actual EventHandler delegate instance from an event in VB.NET?

However, here I am specifically looking at creating an event from a string.

Edit:

In the vb.net/webforms environment, several things are different. As per my comment on the accepted answer, due to (I believe) the nature of the code based model, it is not possible to return the field corresponding to the event from Me.GetType()

, as at runtime Me

refers to class inheritance in the .aspx file and not in the class in the .aspx.vb file.

What this really means is that I have to use the Me.BaseType.GetType()

search field.

The second thing that is different, although unrelated to the final answer, is that while in C # you can directly reference the MulticastDelegate event handler, in vb.net you cannot - or at least do this should use an undocumented feature not supported by intellisense, according to: How can I get the actual EventHandler delegate instance from an event in VB.NET?

+3


source to share


2 answers


The problem I ran into was that iterating through the collection of fields Me.GetType()

did not return the "TestEvent" field. Once again I worked and realized that this is because the event is declared in the "code behind" class, for example: myPageName.aspx.vb, but at runtime this code is called from the inheriting class "design", for example myPageName. ASPX.

This blog post states that even with BindingFlags.FlattenHierarchy

, .GetType.GetField()

will not return private static fields from inherited classes. http://bobpowell.net/eventsubscribers.aspx



As a result, the solution was to use Me.GetType.BaseType.GetField("TestEvent")

and from there use the technique described by Tejas Sharma. This answer offers a vb.net example of this method: How to attach events of a source object to a deeply copied clone

0


source


You can call GetField

on your instance of the type and then move on to the call GetValue()

on the return one FieldInfo

. Here is an example (in C #, because I am not talking about vb.net)



class Foo
{
    public event EventHandler Bar;

}
class Program
{
    static void Main(string[] args)
    {
        var foo = new Foo();
        foo.Bar += FooOnBar;

        var ev = (MulticastDelegate)foo.GetType().GetField("Bar", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(foo);
        if (ev != null)
        {
            foreach (var del in ev.GetInvocationList())
            {
                del.Method.Invoke(del.Target, new object[] {foo, new EventArgs()});
            }
        }
        Console.ReadLine();
    }

    private static void FooOnBar(object sender, EventArgs eventArgs)
    {
        Console.WriteLine("Invoked!");
    }
}

      

+1


source







All Articles