private void Record_Click(object sender, EventArgs e)
        {
            string[] eventsName = getSelectedEvents();
            string[] controlName = getSelectedControls();
            for (int i = 0; i < controlName.Length; i++)
            {
                Control ctrl = controls[controlName[i]];
                foreach (EventInfo eventCtrl in ctrlEvents)
                {
                    foreach (string eventName in eventsName)
                    {
                        if (eventCtrl.Name == eventName)
                        {
                            Type tDelegate = eventCtrl.EventHandlerType;
                            MethodInfo methodToRegister = typeof(FormRecorder).GetMethod("registerInEventsList", BindingFlags.NonPublic | BindingFlags.Instance);
                            Delegate d = Delegate.CreateDelegate(tDelegate, ctrl, methodToRegister);
                            MethodInfo addHandler = eventCtrl.GetAddMethod();
                            Object[] addHandlerArgs = { d };
                            addHandler.Invoke(this, addHandlerArgs);
                        }
                    }
                }
            }
            Form1 form1 = new Form1();
            form1.Show();
        }

ctrl is the control where i'm trying to raise the event, but Delegate d = Delegate.CreateDelegate(tDelegate, ctrl, methodToRegister); gives the following error: "Error binding to target method" if i use "this"(form) instead of the control works fine. Can someone help me with this?

Recommended Answers

All 17 Replies

"controls" should be "Controls". C# is a case sensitive language.

This compiles:

private string[] getSelectedEvents()
    {
      return null;
    }

    private string[] getSelectedControls()
    {
      return null;
    }
    private List<EventInfo> ctrlEvents = default(List<EventInfo>);

    private void button2_Click(object sender, EventArgs e)
    {
      string[] eventsName = getSelectedEvents();
      string[] controlName = getSelectedControls();
      for (int i = 0; i < controlName.Length; i++)
      {
        Control ctrl = Controls[controlName[i]];
        foreach (EventInfo eventCtrl in ctrlEvents)
        {
          foreach (string eventName in eventsName)
          {
            if (eventCtrl.Name == eventName)
            {
              Type tDelegate = eventCtrl.EventHandlerType;
              MethodInfo methodToRegister = typeof(frm1).GetMethod("registerInEventsList", BindingFlags.NonPublic | BindingFlags.Instance);
              Delegate d = Delegate.CreateDelegate(tDelegate, ctrl, methodToRegister);
              MethodInfo addHandler = eventCtrl.GetAddMethod();
              Object[] addHandlerArgs = { d };
              addHandler.Invoke(this, addHandlerArgs);
            }
          }
        }
      }
      //Form1 form1 = new Form1();
      //form1.Show();
    }

"controls" should be "Controls". C# is a case sensitive language.

This compiles:

private string[] getSelectedEvents()
    {
      return null;
    }

    private string[] getSelectedControls()
    {
      return null;
    }
    private List<EventInfo> ctrlEvents = default(List<EventInfo>);

    private void button2_Click(object sender, EventArgs e)
    {
      string[] eventsName = getSelectedEvents();
      string[] controlName = getSelectedControls();
      for (int i = 0; i < controlName.Length; i++)
      {
        Control ctrl = Controls[controlName[i]];
        foreach (EventInfo eventCtrl in ctrlEvents)
        {
          foreach (string eventName in eventsName)
          {
            if (eventCtrl.Name == eventName)
            {
              Type tDelegate = eventCtrl.EventHandlerType;
              MethodInfo methodToRegister = typeof(frm1).GetMethod("registerInEventsList", BindingFlags.NonPublic | BindingFlags.Instance);
              Delegate d = Delegate.CreateDelegate(tDelegate, ctrl, methodToRegister);
              MethodInfo addHandler = eventCtrl.GetAddMethod();
              Object[] addHandlerArgs = { d };
              addHandler.Invoke(this, addHandlerArgs);
            }
          }
        }
      }
      //Form1 form1 = new Form1();
      //form1.Show();
    }

Sknake its not a syntax problem i didn't paste here all the code see here:

private void setControlsListValues(Form form)
        {
            controls = form.Controls;
            foreach (Control control in controls)
            {
                controlsListBox.Items.Add(control.Name);
            }
        }

adatapost neither one of the the three params of the delegate are null in runtime i don't know why it works fine with the form where i'm doing the code but not with one of the controls of the form.
Even if i do this: Delegate d = Delegate.CreateDelegate(tDelegate, this.button1, methodToRegister); give me the same error, why only works with the form and not with the button???

Can you paste the code for the class and any other code required to compile it then?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;

namespace Trab
{
    

    public partial class FormRecorder : Form
    {
        private Control.ControlCollection controls;
        Dictionary<string, string> eventsDict;
        Dictionary<string, string> selCtrlEventsDict;
        Dictionary<string, string> controlsDict;
        Control[] ctrlArray;
        Object control;
        public event EventHandler writeToList;

        public FormRecorder()
        {
            InitializeComponent();
            eventsDict = new Dictionary<string, string>();
            controlsDict = new Dictionary<string, string>();
            selCtrlEventsDict = new Dictionary<string, string>();
        }

        private void setControlsListValues(Form form)
        {
            controls = form.Controls;
            foreach (Control control in controls)
            {
                controlsListBox.Items.Add(control.Name);
            }
        }

        private void setSelectedControls(ItemCheckEventArgs e)
        {
            if (e.NewValue == CheckState.Checked)
            {
                ctrlArray = controls.Find(controlsListBox.GetItemText(controlsListBox.Items[e.Index]), false);
                control = ctrlArray[0];
                controlsDict.Add(controlsListBox.GetItemText(controlsListBox.Items[e.Index]), control.GetType().ToString());
            }
            else if (e.NewValue == CheckState.Unchecked)
            {
                controlsDict.Remove(controlsListBox.GetItemText(controlsListBox.Items[e.Index]));
            }
        }

        private void setEventsChooserValues(ItemCheckEventArgs e)
        {
            ctrlArray = controls.Find(controlsListBox.GetItemText(controlsListBox.Items[e.Index]), false);
            control = ctrlArray[0];
            EventInfo[] events = control.GetType().GetEvents();
            string controlName = "";


            if (e.NewValue == CheckState.Checked)
            {
                foreach (EventInfo evt in events)
                {
                    if (eventsChooserList.Items.Count == 0)
                    {
                        if (!eventsDict.ContainsKey(evt.Name))
                        {
                            eventsDict.Add(evt.Name, control.GetType().ToString());
                            eventsChooserList.Items.Add(evt.Name);
                        }
                    }
                    else
                    {
                        if (!eventsDict.ContainsKey(evt.Name))
                        {
                            eventsDict.Add(evt.Name, control.GetType().ToString());
                            eventsChooserList.Items.Add(evt.Name);

                        }
                    }
                }
            }
            else if (e.NewValue == CheckState.Unchecked)//se o controlo 
            {
                foreach (EventInfo evt in events)
                {
                    if (eventsDict.ContainsKey(evt.Name))
                    {
                        //falta comparar com todos os controlos selecionados na controlcheckedlist
                        if (controlsListBox.CheckedItems.Count != 0)
                        {
                            setSelectedControls(e);
                            foreach (KeyValuePair<string, string> key in controlsDict)
                            {
                                controlName = key.Key;

                                if (controlsDict.ContainsKey(controlName) && eventsDict.ContainsKey(evt.Name))//verifica se existe algum controlo na lista de controlos selecionados se existir...
                                {
                                    if (controlsDict[controlName] != eventsDict[evt.Name])//se existir algum controlo mas for de tipo diferente...
                                    {
                                        Object selectedListControl = controls[controlName];
                                        EventInfo[] selectedControlListEvents = selectedListControl.GetType().GetEvents();
                                        foreach (EventInfo selEvt in selectedControlListEvents)
                                        {
                                            if (!selCtrlEventsDict.ContainsKey(selEvt.Name))//se não existir o nome do evento na lista de eventos então adiciona-o
                                            {
                                                selCtrlEventsDict.Add(selEvt.Name, selectedListControl.GetType().ToString());
                                            }
                                        }
                                        if (!selCtrlEventsDict.ContainsKey(evt.Name))
                                        {
                                            eventsChooserList.Items.Remove(evt.Name);
                                            eventsDict.Remove(evt.Name);
                                        }
                                    }
                                }
                                else //se a lista de controlos selecionados estiver vazia entao remove todos os eventos da lista de eventos
                                {
                                    eventsChooserList.Items.Remove(evt.Name);
                                    eventsDict.Remove(evt.Name);
                                }
                            }
                            if (controlsDict.Count == 0)
                            {
                                eventsChooserList.Items.Remove(evt.Name);
                                eventsDict.Remove(evt.Name);
                            }
                        }
                    }
                }
            }
        }



        private void FormRecorder_Load(object sender, EventArgs e)
        {
            setControlsListValues(new Form1());
        }

        private void ControlsListBox_ItemCheck(Object sender, ItemCheckEventArgs e)
        {
            setSelectedControls(e);
            setEventsChooserValues(e);
        }


        private string[] getSelectedEvents()
        {
            string[] eventsArray = new string[eventsChooserList.CheckedItems.Count];
            for (int i = 0; i < eventsChooserList.CheckedItems.Count; i++)
            {
                eventsArray[i] = eventsChooserList.CheckedItems[i].ToString();
            }
            return eventsArray;
        }
        private string[] getSelectedControls()
        {
            string[] controlsArray = new string[controlsListBox.CheckedItems.Count];
            for (int i = 0; i < controlsListBox.CheckedItems.Count; i++)
            {
                controlsArray[i] = controlsListBox.CheckedItems[i].ToString();
                Console.WriteLine(controlsArray[i]);
            }
            return controlsArray;
        }


        private void registerInEventsList(Object sender, EventArgs e)
        {
            eventListBox.Items.Add("Registei");
        }

        /*public void addWriter(writeToList w)
        {
            this.write += w;
        }

        public void removeWriter(writeToList w)
        {
            this.write -= w; 
        }*/

        private void Record_Click(object sender, EventArgs e)
        {
            string[] eventsName = getSelectedEvents();
            string[] controlName = getSelectedControls();

            //writeToList w1 = registerInEventsList;
            //this.addWriter(w1);
            writeToList += new EventHandler(registerInEventsList);

            for (int i = 0; i < controlName.Length; i++)
            {
                Object ctrl = controls[controlName[i]];
                EventInfo[] ctrlEvents = ctrl.GetType().GetEvents();
                foreach (EventInfo eventCtrl in ctrlEvents)
                {
                    foreach (string eventName in eventsName)
                    {
                        if (eventCtrl.Name == eventName)
                        {
                            
                            //Type tDelegate = eventCtrl.EventHandlerType;
                            //MethodInfo methodToRegister = typeof(FormRecorder).GetMethod("registerInEventsList", BindingFlags.NonPublic | BindingFlags.Instance);
                            //Delegate d = Delegate.CreateDelegate(tDelegate, ctrl, methodToRegister);
                            MethodInfo addHandler = eventCtrl.GetAddMethod();
                            Object[] addHandlerArgs = { writeToList };
                            addHandler.Invoke(this, addHandlerArgs);
                        }
                    }
                }
            }
            Form1 form1 = new Form1();
            form1.Show();
        }

        //disparar evento
        /*public event EventHandler<EventArgs> MyEventToBeFired; 

        public void FireEvent(Guid instanceId, string handler) 
        {

            // Note: this is being fired from a method with in the same class that defined the event (i.e. "this").


            EventArgs e = new EventArgs(instanceId); 

            MulticastDelegate eventDelagate = 
                  (MulticastDelegate)this.GetType().GetField(handler, 
                   System.Reflection.BindingFlags.Instance | 
                   System.Reflection.BindingFlags.NonPublic).GetValue(this); 

            Delegate[] delegates = eventDelagate.GetInvocationList(); 

            foreach (Delegate dlg in delegates) 
            { 
                dlg.Method.Invoke(dlg.Target, new object[] { this, e }); 
            } 
        } 
        FireEvent(new Guid(),  "MyEventToBeFired");*/ 
    }
}

at this moment i created the delegate of type event by myself and i'm not using reflection but now dont give me any error but dont do nothing.

OK, one step one closer. Now let me ask -- What are you trying to do? Find all associated events for the controls that are selected? If that so is the specific question "how to enumerate events on a control, and enumerage all of the delegates for each event?"

There is a lot of code there. I mocked up the form but its still missing code for the other Form1 :P Upload a sample project if you can.

I'm trying to add to some events of the controls a delegate with a function that i created.
At this moment i have a delegate of type eventHandler made by me.
Now don't give any error but nothing happens.
Here is the attachment

Yes but explain what you are trying to do. I have the application loaded but what should i do. Select a control, then event, then do ... ? And which line of code is not working?

You want to select any control and any event on those controls and assign them the same delegate?

In the first list box you have the kind of control you want to record and in list below you have the events you want to record from the Form1.

If you choose button1 and after that the event click in the list, when you play record and you click in the the button1 of the calculator its suppose to write in the right list box "Registei".

OK, I fixed your project. The controls+events are now sorted, the "Select All" and "Select None" now work, and the dynamic event works. It is tested against button6.Click -- but you can see what I changed and work on it from there.

You better mark this thread as solved! :P I spent over half an hour on this thing.

Man thanks a lot for your time i will test it and try to understand what i did wrong.

No problem --- please mark this thread as solved. The core of the problem is
1) You were creating the form to get the control names and their events. Then you created a NEW form after you tried to assign the events. You have to use the same form you assigned the events on.
2) Where the CreateDelegate was failing to bind i changed it to:

Type tDelegate = eventCtrl.EventHandlerType;
              MethodInfo methodToRegister = this.GetType().GetMethod("registerInEventsList", BindingFlags.Public | BindingFlags.Instance);
              Delegate d = Delegate.CreateDelegate(tDelegate, this, methodToRegister, true);
              eventCtrl.AddEventHandler(ctrl, d);

I also changed the access modifier on the event to public since you were calling it from another class. I'm not sure if it would have worked with reflection (probably would have) but you will need to test that.

commented: Very good explanation. +7

I didn't marked this thread as solved because i'm trying to do the same thing but with a delegate created by me i'm only doing this because it's a lot more expensive create a delegate by reflection.
Here is the version with the delegate created without reflection.
I did several mistakes the major one was like you said i was creating a new form. By the way i added you reputation, you deserved it.

You changed what you were doing.......... I don't think it would be wise on my part to fix+upload another project if you're going to change how you are going about things.

No i'm only posting the version with the delegate creation without reflection, because could help someone else all the other changes you made i will keep them :).
Once more thanks a lot i added you reputation because you deserved it.

Thanks Scott,
You are always right. I appreciate your knowledge.

Thanks Scott,
You are always right. I appreciate your knowledge.

pffft you, ramy, danny, and serkan have all proved me wrong more than once :P but thats a good thing because you learn from it!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.