关于EVENT属性

oniisama 2011-10-13 07:28:07
using System;
using System.Windows.Forms;
using System.Drawing;

public class FlashTrackBar : Control {
// The event does not have any data, so EventHandler is adequate

// as the event delegate.

private EventHandler onValueChanged;
// Define the event member using the event keyword.

// In this case, for efficiency, the event is defined

// using the event property construct.

public event EventHandler ValueChanged {
add {
onValueChanged += value;
}
remove {
onValueChanged -= value;
}
}
// The protected method that raises the ValueChanged

// event when the value has actually

// changed. Derived controls can override this method.

protected virtual void OnValueChanged(EventArgs e) {
if (ValueChanged != null) {
ValueChanged(this, e);
}
}
}


这段代码是MSDN上的,编译没通过,请问是不是应该把最后两行的ValueChanged改成onValueChanged?
...全文
141 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
oniisama 2011-10-14
  • 打赏
  • 举报
回复
我明白了。就是要另外添加一个字典之类的集合来保存eventhandler来实现这个功能。哈哈,谢谢各位大大的解说。
  • 打赏
  • 举报
回复
不论你使用哪一种事件编程方式,总之你要调用最终的EvengHandler。当你写你的那种 add/remove 方式的时候,你怎么可能调用执行 ValueChanged 呢?因为它根本没有返回 EventHandler的功能,而只有 add/remove功能。所以你当然需要调用 onValueChanged 这个目标 EvengHandler。
  • 打赏
  • 举报
回复
既然不用省事的方法写,那么当然就要用费事的方法调用。有的时候我们写烂代码不是因为学的太少了,可能是因为学的太多了并且一知半解,于是纠结。

.net的控件之所以会那样写,根本不是你这个模式。而如果你要按照普通的模式来在c#中使用Event,写
public event EventHandler ValueChanged;
就足够了。
  • 打赏
  • 举报
回复
当然要写成
if (onValueChanged != null)
{
onValueChanged(this, e);
}


在微软自己的控件中,事件的设计模式是这样的:
private static readonly EventHandler onValueChanged;

public event EventHandler ValueChanged
{
add
{
base.Events.AddHandler(onValueChanged, value);
}
remove
{
base.Events.RemoveHandler(onValueChanged, value);
}
}

protected virtual void OnValueChanged(EventArgs e)
{
EventHandler handler = (EventHandler) base.Events[onValueChanged];
if (handler != null)
{
handler(this, e);
}
}


也就是说,每个控件中有一个队列,保存所有各种类型的EventHandler。比如说一个控件有30个事件,比如说其中只有5个被使用并且注册了8个EvengHandler实例,那么此控件实例对象内部的这个事件队列中有5个Delegate,这5个Delegate(其中有的是MuticastDelegate)总共组合了8个具体的(单一的)Delegate。
classbob 2011-10-14
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 oniisama 的回复:]

引用 4 楼 classbob 的回复:

对于implict event,就是public event EventHandler ValueChanged;这样的定义,编译器会生成一个delegate及相应的add,remove方法,你引用ValueChanged(如ValueChanged(...)),编译器会使用生成的那个delegate来代替,而+=、-=会调用生成的add、remo……
[/Quote]
不是关联,编译器遇到你对ValueChanged的调用,就会生成对那个private delegate调用的IL,具体你可以自己写个小例子看看生成的IL代码
定义explicit event就是相当于这个功能呀,比如你的onValueChange就相当于编译器生成的那个delegate
星小野 2011-10-14
  • 打赏
  • 举报
回复
关注...
oniisama 2011-10-14
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 classbob 的回复:]

对于implict event,就是public event EventHandler ValueChanged;这样的定义,编译器会生成一个delegate及相应的add,remove方法,你引用ValueChanged(如ValueChanged(...)),编译器会使用生成的那个delegate来代替,而+=、-=会调用生成的add、remove方法
对于explict event,就是……
[/Quote]

定义implict event之后,可以直接通过event调用那个自动生成的delegate,编译器是怎么把自动生成的delegate跟那个event关联起来的呢?我们自己也可以实现这个功能吗?
classbob 2011-10-13
  • 打赏
  • 举报
回复
对于implict event,就是public event EventHandler ValueChanged;这样的定义,编译器会生成一个delegate及相应的add,remove方法,你引用ValueChanged(如ValueChanged(...)),编译器会使用生成的那个delegate来代替,而+=、-=会调用生成的add、remove方法
对于explict event,就是定义了add,remove的event,那么编译器就不会生成那个delegate了,所以你只能+=、-=,这时候调用的就是你自定义的add、remove方法了
存在的价值自然是有的,你可以在add、remove里做更多的控制
oniisama 2011-10-13
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 classbob 的回复:]

要么去掉ValueChanged的add、remove,要么调用onValueChanged
[/Quote]

那究竟ValueChanged有什么存在价值,是不是没有办法直接通过Event属性调用EventHandler?
classbob 2011-10-13
  • 打赏
  • 举报
回复
要么去掉ValueChanged的add、remove,要么调用onValueChanged
xiongxyt2 2011-10-13
  • 打赏
  • 举报
回复

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace wanwan2
{
public class WarnEventArgs : EventArgs
{
private double _tempature = 0.0;

public double Tempature
{
get { return _tempature; }
set { _tempature = value; }
}

}
public class BoilWater
{

public delegate void WarnDelegate(WarnEventArgs e);
public event WarnDelegate WarnEvent;



public void OnWarnEvent(WarnEventArgs e)
{
if (WarnEvent!= null)
{
WarnEvent(e);
}
}

public void Warn(double x)
{
WarnEventArgs e = new WarnEventArgs();
e.Tempature = x;
OnWarnEvent(e);
}
}

class Program
{

public static void Alarm(WarnEventArgs e)
{
double tem = e.Tempature;
while (tem > 97 && tem < 101)
{
Console.WriteLine("是快开了,现在已经达到{0}摄氏度",tem);
tem++;
}
}

static void Main(string[] args)
{
BoilWater _warter = new BoilWater();
_warter.WarnEvent += Alarm;
_warter.Warn(98);
}
}
}

111,125

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧