Solved

CreateInstance points to wrong function ...

Posted on 2008-10-28
9
271 Views
Last Modified: 2013-12-27
Hi,

I like to create some buttons dynamic with the NET CF2 (Custom Controls) and also delegate them dynamic to an event.
So I get the hint how to use CreateInstance to delegte to a function at runtime.
At all it works but one problem is there I can't solve - all of my buttons pint to the same function, the last one I use - in this case My4_Click

So can somebody please point me the problem why any button points to the same function?
When I debug I see that the CreateInstance contains the right function name.

Can somebody help please?

Thanks,

Andre
namespace mynamespace

{

public sealed class myfunctions

{

public static void My1_Click(object sender, EventArgs e)

{

MessageBox.Show("Funktion 1");

}
 

public static void My2_Click(object sender, EventArgs e)

{

MessageBox.Show("Funktion 2");

}
 

public static void My3_Click(object sender, EventArgs e)

{

MessageBox.Show("Funktion 3");

}
 

public static void My4_Click(object sender, EventArgs e)

{

MessageBox.Show("Funktion 4");

}

}

}
 

namespace mynamespace

{

public partial class Form1 : Form

{
 

Type TargetScr;

object TargetObj;

MethodInfo TargetMethod;

EventHandler[] TargetHandler = new EventHandler[10];
 

public Form1()

{

TargetScr = Type.GetType("mynamespace.myfunctions");

for(int i=0;i<4;i++)

{

Button but = new Button();

...

TargetObj = Activator.CreateInstance(TargetScr);

TargetMethod = TargetObj.GetType().GetMethod("My" + i.ToString() + "_Click");

TargetHandler[ i ] = delegate(object s, EventArgs e)

{

TargetMethod.Invoke(this, new object[] { s, e });

};

but.GetType().GetEvent("Click").AddEventHandler(but, TargetHandler[ i ]);

}

}

}

}

Open in new window

0
Comment
Question by:andre72
  • 5
  • 4
9 Comments
 
LVL 19

Expert Comment

by:drichards
Comment Utility
You are using the variable TargetMethod inside the anonymous delegate.  It ends with the value of the last method retrieved from GetMethod.  Not immediately sure of a way to fix it.
0
 

Author Comment

by:andre72
Comment Utility
Ok, I see the matter but I need a solution. Maybe there's an other way to get a simular result - to give any of the button it's own Event?
0
 
LVL 19

Expert Comment

by:drichards
Comment Utility
Normally, you'd just do:

   but.Click += new EventHandler(My1_Click);

Unfortunately, this won't work in a loop like you're doing because you can't use a MthodInfo instance to create the event handler delegate.  You'd need to special case each iteration to assign the correct function.  I'll think about how you might do what you're attempting with the loop and reflection there.
0
 

Author Comment

by:andre72
Comment Utility
I can't use this - in this case My1_Click has to be an Object but I've only the name (as a string) of the function. So I need a delegate because I've to get the function first...
0
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 

Author Comment

by:andre72
Comment Utility
I've the solution - just use the delegate in it's own function ... Use it's in a loop will overwrite the stack with every loop - I don't know why ... But when you call a function the delegate will be stored when you leave the funktion ... Thanks at all
0
 
LVL 19

Expert Comment

by:drichards
Comment Utility
Yes, that should work.  The delegate captures a reference to the outer variable when it is created, so if you create the delegate in a separate function with a local variable which I assume you pass in as a parameter, the delegate captures a reference to the function local which will be different on each call and not overwritten like the class member variable you were using previously.
0
 
LVL 19

Expert Comment

by:drichards
Comment Utility
And after some yoga to relax the mind and body...

You don't need an extra method.  If you just make TargetMethod local to the loop you get the same effect.  In fact, why are any of those variables class members since you don't need them except to set up the buttons?  I've included some code that streamlines your function a bit, doesn't introduce an extra function, and eliminates what appear to be unnecessary items, though since I don't know your design you may need them after all.
namespace mynamespace

{

    public partial class Form1 : Form

    {

        EventHandler[] TargetHandler = new EventHandler[10];
 

        public Form1()

        {

            // Only need one instance of the class...

            TargetObj = Activator.CreateInstance(typeof(myfunctions));

            for (int i = 0; i < 4; i++)

            {

                Button but = new Button();

                ...

                MethodInfo TargetMethod = TargetObj.GetType().GetMethod("My" + (i+1).ToString() + "_Click");

                TargetHandler[i] = delegate(object s, EventArgs e)

                {

                    TargetMethod.Invoke(this, new object[] { s, e });

                };

                but.GetType().GetEvent("Click").AddEventHandler(but, TargetHandler[i]);

            }

        }

    }

}

Open in new window

0
 

Author Comment

by:andre72
Comment Utility
Have you tried it out? I'd looked for a solution for two days and stand a couple of hours with, make the MethodInfo to an Array,make TargetObj to an Array. TargetObj outside the loop (like in your example) , tried MethodInfo TargetMethod = TargetScr.GetMethod("My" + (i+1).ToString() + "_Click"); and so on... I tried anything in the time to make it work - and ever the same result ... So I'm nearly sure that I'd tried out only one instance with the same result ...
0
 
LVL 19

Accepted Solution

by:
drichards earned 250 total points
Comment Utility
Yes, I ran the code as shown except that I was not assigning the delegates to a button click.  I just cycled through the handler array after setting all the elements to verify that they each invoked the correct method in myfunctions.

If you are not doing anything with the array, you don't really need it since in your case the buttons hold on to the event delegates.  
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Once again I push the limits of my phone.  An introduction to the Android Google Now Launcher.
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
This video discusses moving either the default database or any database to a new volume.
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

7 Experts available now in Live!

Get 1:1 Help Now