Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

CreateInstance points to wrong function ...

Posted on 2008-10-28
9
Medium Priority
?
283 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
Veeam Disaster Recovery in Microsoft Azure

Veeam PN for Microsoft Azure is a FREE solution designed to simplify and automate the setup of a DR site in Microsoft Azure using lightweight software-defined networking. It reduces the complexity of VPN deployments and is designed for businesses of ALL sizes.

 

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 1000 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

Stressed Out?

Watch some penguins on the livecam!

Question has a verified solution.

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

Preface: This article is part of a series focused on cross platform mobile app development (specifically Android and iOS) using the Alloy framework and Titanium Studio made by Appcelerator (https://www.appcelerator.com/). This article presumes a wor…
If you are anything like me, you install many apps on your phone and have your life on it, sometimes literally.  When I bought my current phone, a Samsung Galaxy S5 from Verizon, they were only selling the versions with 16 GB internal.  I didn't rea…
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…
Suggested Courses

721 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