Question

I have been tinkering with Events to gain a better understanding of their use in very general situations. I'm surprised to find the following, so I'm probably heading in the wrong direction...the essence of what I'm doing is changing a button to a random color when it is clicked:

Windows Form

public Form1()       
{ 

ColorChanges KK = new ColorChanges();

KK.ColorEventHandler += handle_ColorChanges;

button1.Click += delegate { KK.ChangeColor(button1); };

}

Event Class

class ColorChanges
{

   *... properties & constructor*

   public void ChangeColor(object sender)
   {
   *... randomly assign color to ColorEventArgs*
   }

   protected virtual void onColorEvent(object sender, ColorEventArgs e)
   {
      EventHandler<ColorEventArgs> ceh = ColorEventHandler;
      {   
      if (ceh != null)
         {
         ceh(sender, e)             
         }
     }
   }

   public event EventHandler<ColorEventArgs> ColorEventHandler;
}

Custom Event Args

public class ColorEventArgs : EventArgs
{
  public Color xColor { get; set; }
}

Event Handler

public void handle_ColorChanges(object sender, ColorEventArgs e)
{
   if (sender is Button)
      {
       var ButtonSender = (Button)sender;

       ButtonSender.BackColor = e.xColor;
       }
}

So the edited questions are:

Is use of the EventHandler(TEventArgs) Delegate useful? MS documentation indicates that syntax like

  button1.Click += new EventHandler<AutoRndColorEventArgs>(handle_ColorChanges);

is correct, but that will not reach my code to randomly select a color and an error

"No overload for 'handle_ColorChanges' matches delegate >'System.EventHandler' "

so something like

button1.Click += new EventHandler<AutoRndColorEventArgs>(KK.ChangeColor(button1));

or

button1.Click += new EventHandler(KK.ChangeColor(button1));

Error says that a method is required and if I use

"No overload for 'handle_ColorChanges' matches delegate 'System.EventHandler'"

Lambda expressions help thanks for the supporting answers

button1.Click += (sender,args) => KK.ChangeColor(s); 

But that doesn't allow un-assignment and that will be required later...

An anonymous delegate has the same problem

button1.Click += delegate(object sender, EventArgs e)
            { KK.ChangeColor(sender); };

The crux of the problem is that my color methods or their delegates do not match the button delegate signature (object, event). I don't care about the button args and want to use my own HOW?

Was it helpful?

Solution

Is the use of the delegate correct?

Yep, what you are doing is assigning an anonymous delegate as your event handler. This is perfectly valid, however, the catch here is you can't unassign the event handler because you have no reference to it. You could keep a reference to it and do it that way (if required)

var clickHandler = delegate { ... };
button1.Click += clickHandler;
...
button1.Click -= clickHandler

If you need access to the parameters of the event handler you will need to add those into the signature e.g.

button1.Click += delegate (object sender, EventArgs args) { ... }

The new EventHandler(SomeHandlerMethod) construct is the long way of doing things, it's synonymous to += SomeHandlerMethod. Your code currently doesn't work because you are trying to actually call the handler inside the constructor when the constructor expects a reference to the method

+= new EventHandler<ColorEventArgs>(KK.ChangeColor);

Is there a better structure for this?

Yeah, you can do it using even less code

button1.Click += (s, args) => KK.ChangeColor(button1);

OTHER TIPS

This is incorrect:

button1.Click += new EventHandler<AutoRndColorEventArgs>(KK.ChangeColor(button1));

Instead of KK.ChangeColor(button1), you just need to specify the event handler method name as you did in here:

KK.ColorEventHandler += handle_ColorChanges;

The event handler method signature should match with the EventHandler delegate.If you want to just call a method in event handler, you can use lambda statement like this:

button1.Click += (s,e) => KK.ChangeColor(s);

Or:

button1.Click += delegate(object s, EventArgs e) { KK.ChangeColor(s); };

By doing this you are creating an anonymous method and attach it to your Click event.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top