Click here to Skip to main content
15,882,017 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have a form that may contain several instances of the same control depending on the application. Some applications will need a handful, others will need 40+ of these controls. In VB6 I would add controls to the form manually, assign a meaningful name and then double click the control to implement an event handler. The event handler will be very different from control to control.

I am new to doing events in C# but I think the way I would implement the event for each control is as follows:

C#
Control1.Operate += new MyControl.OperateEventHandler(Control1_Operate);
.
.
.
Control10.Operate += new MyControl.OperateEventHandler(Control10_Operate);


Then I would implement the code in Control1_Operate and so on.

But I would rather not have to do the above every time I add a control to the screen. I would like C# to handle it for me like below but I get stuck when I need to provide the actual event handler.

C#
foreach (Control ctrl in this.Controls)
{
    if (ctrl.GetType() == typeof(UniControl))
    {
        temp = (UniControl)ctrl;
        temp.Operate += new UniControl.OperateEventHandler(Generic_Operate);
    }
}


If I use a Generic_Operate handler then I will somehow need to a have reference to the control that needs to be operated. Or can I somehow auto generate the handler "name" like this:

C#
foreach (Control ctrl in this.Controls)
{
    if (ctrl.GetType() == typeof(UniControl))
    {
        temp = (UniControl)ctrl;
        temp.Operate += new UniControl.OperateEventHandler(temp.Name + "_Operate");
    }
}


Obviously the above won't work but maybe there's a way to get the effect I want?
Posted

Event handlers have a sender property which you can use to get the control that fired.

If all your event handlers are similar just use one handler and use the sender property.
 
Share this answer
 
Comments
Manfred Rudolf Bihy 3-Nov-11 14:52pm    
Essentially what I think. 5+
Mehdi Gholam 3-Nov-11 14:57pm    
Thanks
David J Perez 3-Nov-11 15:55pm    
I think this would work as you described but then I will have just moved the problem I have to the generic handler where I would then have to explicitly call each individual handler since the handlers will be wildly different.
Depends on the delegate definition for your Operate event handler. The event handler should accept a parameter which would contain a reference to the control that raised the event. If the control is your own you can take a look at the source code and see if the event delegate was properly defined to allow the passing of an EventArgument or a derivat thereof as a parameter to the event handler. If you don't have the source code of the control and the event handler delegate does not have a parameter this won't work.

Regards,

—MRB
 
Share this answer
 
Comments
Mehdi Gholam 3-Nov-11 14:59pm    
5'ed
David J Perez 3-Nov-11 15:57pm    
I can make changes to the control and add the standard event params but I would have to deal with this problem again in the generic handler.
The event handler should pass the source of the event as one of its parameters. The built in types all pass the source (sender, by .Net convention) as the first argument as an object. This looks like a custom delegate, so make sure it passes the source of the event as the first argument – you can either make it object like the built-in types or, if it only makes sense on one type of object, you can use that type, i.e.

class MyControl {
 delegate void SomeSpecialistEventHandler(MyControl sender, int magicNumber, Color favouriteColour);
 // ...
}


Then, in the handler, you can use the first parameter to find out which control you were fired on:

void MySpecialistEventHandler(MyControl sender, int magicNumber, Color favouriteColour){
 // Use 'sender' when you need the object that triggered the event
}

void NormalButton_Click(object sender, EventArgs e){
 Button button = sender as Button;
 // Use 'button' as the typed source
 // If this event can be fired by different types, put a guard in, e.g.
 //  if(button == null) return;
 // but generally you shouldn't make that possible.
}
 
Share this answer
 
Comments
Manfred Rudolf Bihy 3-Nov-11 14:54pm    
Agreed! 5+
David J Perez 3-Nov-11 15:59pm    
I can make changes to the control and add the standard event params but I would then have a switch/case tree to explicitly call the specific (as opposed to generic) handlers.
Guys explained right, you can also see this solution me

You can have only one handler, like this for all your control:

C#
foreach (Control ctrl in this.Controls)
{
    if (ctrl.GetType() == typeof(UniControl))
    {
        temp = (UniControl)ctrl;
        temp.Operate += new UniControl.OperateEventHandler(temp, control_operate);
    }
}


Then into this event function, manage controls easily;)

C#
void control_operate(object sender, OperateEventHandler e)
{
    switch ((sender as yourControlType).Tag.ToString())
    {
        case "Control0":
            // code about Control0
            break;
        case "Control1":
            break;
        case "Control2":
            break;
            .
            .
            .
        case "Controln":
            break;
        default:
            break;
    }
}


I think you have 2 way:
1. If controls does same work:
C#
void control_operate(object sender, OperateEventHandler e)
{
    (sender as yourCntType).Enabled = false;
    ///...
}


2. O.W. If controls doesn't same work, you write all states exactly (write all cases):
C#
void control_operate(object sender, OperateEventHandler e)
{
    switch ((sender as yourControlType).Tag.ToString())
    {
        case "Control0":
            // code about Control0
            break;
        case "Control1":
            // code about Control1
            break;
        case "Control2":
            // code about Control2
            break;
        case "Control3":
            // code about Control3
            break;
        default:
            break;
    }
}
 
Share this answer
 
v4
Comments
David J Perez 3-Nov-11 16:04pm    
So when I add a new control to a form instead of assigning a specific handler in my constructor I would add a new case to my generic handler. I would not have gained much.
hzawary 3-Nov-11 17:11pm    
Ok! you want a dynamic switch case!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900