+ = delegate {}是将自定义eventargs附加到UI控件事件的正确方法吗?

时间:2014-03-19 15:24:26

标签: c# events eventargs

我一直在修改事件,以便更好地了解它们在一般情况下的使用情况。我很惊讶地发现以下内容,所以我可能朝着错误的方向前进......我所做的就是在点击按钮时将按钮更改为随机颜色:< / p>

Windows窗体

public Form1()       
{ 

ColorChanges KK = new ColorChanges();

KK.ColorEventHandler += handle_ColorChanges;

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

}

活动类

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;
}

自定义事件参数

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

事件处理程序

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

       ButtonSender.BackColor = e.xColor;
       }
}

所以编辑的问题是:

使用EventHandler(TEventArgs)委托有用吗? MS文档表明语法如

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

是正确的,但是我的代码无法随机选择颜色和错误

  

&#34;&#39; handle_ColorChanges&#39;匹配委托&gt;&#39; System.EventHandler&#39; &#34;

类似

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

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

错误说需要一个方法,如果我使用

  

&#34;&#39; handle_ColorChanges&#39;匹配代表   &#39; System.EventHandler&#39;&#34;

Lambda表达式帮助感谢支持的答案

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

但这并不允许取消分配,以后需要......

匿名代表有同样的问题

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

问题的症结在于我的颜色方法或其代理与按钮代理签名(对象,事件)不匹配。我不关心按钮args并且想要使用我自己的 如何?

2 个答案:

答案 0 :(得分:2)

这是不正确的:

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

而不是KK.ChangeColor(button1),您只需要像在此处一样指定事件处理程序方法名称:

KK.ColorEventHandler += handle_ColorChanges;

事件处理程序方法签名应该与EventHandler委托匹配。如果你想在事件处理程序中调用一个方法,你可以像这样使用lambda语句:

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

或者:

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

通过执行此操作,您将创建匿名方法并将其附加到Click事件。

答案 1 :(得分:2)

  

委托的使用是否正确?

是的,您正在做的是将 anonymous delegate 指定为事件处理程序。这是完全有效的,但是,这里的问题是您无法取消分配事件处理程序,因为您没有引用它。您可以保留对它的引用并以这种方式执行(如果需要)

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

如果您需要访问事件处理程序的参数,则需要将其添加到签名中,例如

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

new EventHandler(SomeHandlerMethod)构造是漫长的做事方式,它与+= SomeHandlerMethod同义。您的代码目前无法正常工作,因为当构造函数需要引用方法

时,您试图实际调用构造函数内的处理程序
+= new EventHandler<ColorEventArgs>(KK.ChangeColor);
  

这有更好的结构吗?

是的,您甚至可以使用 less 代码

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