tags:

views:

1366

answers:

3

I have this piece of code that not work

public CartaoCidadao()
    {
        InitializeComponent();

        object o = WebDAV.Classes.SCWatcher.LoadAssembly();
        MethodInfo method = this.GetType().GetMethod("Inserted", BindingFlags.NonPublic | BindingFlags.Instance);
        EventInfo eventInfo = o.GetType().GetEvent("CardInserted");
        Type type = eventInfo.EventHandlerType;
        Delegate handler = Delegate.CreateDelegate(type, this , method);

        eventInfo.AddEventHandler(o, handler);
    }


    void Inserted(string readerName, string cardName)
    {
        System.Windows.Forms.MessageBox.Show(readerName);
    }

The Event CardInserted exists in another dll and object "o" load ok. Delegate handler have value after affect, i only can't fire event.

+1  A: 

Here's a sample showing how to attach an event using reflection:

class Program
{
    static void Main(string[] args)
    {
        var p = new Program();
        var eventInfo = p.GetType().GetEvent("TestEvent");
        var methodInfo = p.GetType().GetMethod("TestMethod");
        Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, p, methodInfo);
        eventInfo.AddEventHandler(p, handler);

        p.Test();
    }

    public event Func<string> TestEvent;

    public string TestMethod()
    {
        return "Hello World";
    }

    public void Test()
    {
        if (TestEvent != null)
        {
            Console.WriteLine(TestEvent());
        }
    }
}
Darin Dimitrov
A: 

When you say it doesn't work... what happens? Nothing? An exception?

Thoughts:

  • are both the event and the handler public? If not, you'll need to pass suitable BindingFlags to the GetEvent / GetMethod calls.
  • does the signature of the handler match?

Here's a working example (note I'm using a static handler, hence the null in Delegate.CreateDelegate):

using System;
using System.Reflection;
class Test
{
    public event EventHandler SomeEvent;
    public void OnSomeEvent()
    {
        if (SomeEvent != null) SomeEvent(this, EventArgs.Empty);
    }
    static void Main()
    {
        Test obj = new Test();
        EventInfo evt = obj.GetType().GetEvent("SomeEvent");
        MethodInfo handler = typeof(Test)
            .GetMethod("MyHandler");
        Delegate del = Delegate.CreateDelegate(
            evt.EventHandlerType, null, handler);
        evt.AddEventHandler(obj, del);

        obj.OnSomeEvent();
    }

    public static void MyHandler(object sender, EventArgs args)
    {
        Console.WriteLine("hi");
    }
}
Marc Gravell
I don't see anything. Nothing happen.
pho3nix
+1  A: 

Here's a short but complete example which does work:

using System;
using System.Reflection;

class EventPublisher
{
    public event EventHandler TestEvent;

    public void RaiseEvent()
    {
        TestEvent(this, EventArgs.Empty);
    }
}

class Test
{

    void HandleEvent(object sender, EventArgs e)
    {
        Console.WriteLine("HandleEvent called");
    }

    static void Main()
    {
        // FInd the handler method
        Test test = new Test();
        EventPublisher publisher = new EventPublisher();
        MethodInfo method = typeof(Test).GetMethod
            ("HandleEvent", BindingFlags.NonPublic | BindingFlags.Instance);

        // Subscribe to the event
        EventInfo eventInfo = typeof(EventPublisher).GetEvent("TestEvent");
        Type type = eventInfo.EventHandlerType;
        Delegate handler = Delegate.CreateDelegate(type, test, method);

        // Raise the event
        eventInfo.AddEventHandler(publisher, handler);
        publisher.RaiseEvent();
    }    
}

Now when you say "i only can't fire event" what exactly do you mean? You're not meant to be able to raise events yourself - it's up to the event publisher to do that. Does all of the code you've actually presented to us work? If so, it seems that it's not adding the event handler that's the problem.

Could you give more information?

Jon Skeet