Solved

CreateInstance points to wrong function ...

Posted on 2008-10-28
9
280 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
9 Comments
 
LVL 19

Expert Comment

by:drichards
ID: 22827785
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
ID: 22829208
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
ID: 22830781
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
Salesforce Has Never Been Easier

Improve and reinforce salesforce training & adoption using WalkMe's digital adoption platform. Start saving on costly employee training by creating fast intuitive Walk-Thrus for Salesforce. Claim your Free Account Now

 

Author Comment

by:andre72
ID: 22830824
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
 

Author Comment

by:andre72
ID: 22831033
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
ID: 22836675
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
ID: 22837587
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
ID: 22838800
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
ID: 22839151
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

Veeam gives away 10 full conference passes

Veeam is a VMworld 2017 US & Europe Platinum Sponsor. Enter the raffle to get the full conference pass. Pass includes the admission to all general and breakout sessions, VMware Hands-On Labs, Solutions Exchange, exclusive giveaways and the great VMworld Customer Appreciation Part

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this article we will discuss all things related to StageFright bug, the most vulnerable bug of android devices.
This article shows how to deploy dynamic backgrounds to computers depending on the aspect ratio of display
In this video, viewers will be given step by step instructions on adjusting mouse, pointer and cursor visibility in Microsoft Windows 10. The video seeks to educate those who are struggling with the new Windows 10 Graphical User Interface. Change Cu…
Michael from AdRem Software outlines event notifications and Automatic Corrective Actions in network monitoring. Automatic Corrective Actions are scripts, which can automatically run upon discovery of a certain undesirable condition in your network.…
Suggested Courses

630 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