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?

解决方案 »

  1.   


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

  2.   

    要么去掉ValueChanged的add、remove,要么调用onValueChanged
      

  3.   


    那究竟ValueChanged有什么存在价值,是不是没有办法直接通过Event属性调用EventHandler?
      

  4.   

    对于implict event,就是public event EventHandler ValueChanged;这样的定义,编译器会生成一个delegate及相应的add,remove方法,你引用ValueChanged(如ValueChanged(...)),编译器会使用生成的那个delegate来代替,而+=、-=会调用生成的add、remove方法
    对于explict event,就是定义了add,remove的event,那么编译器就不会生成那个delegate了,所以你只能+=、-=,这时候调用的就是你自定义的add、remove方法了
    存在的价值自然是有的,你可以在add、remove里做更多的控制
      

  5.   


    定义implict event之后,可以直接通过event调用那个自动生成的delegate,编译器是怎么把自动生成的delegate跟那个event关联起来的呢?我们自己也可以实现这个功能吗?
      

  6.   

    不是关联,编译器遇到你对ValueChanged的调用,就会生成对那个private delegate调用的IL,具体你可以自己写个小例子看看生成的IL代码
    定义explicit event就是相当于这个功能呀,比如你的onValueChange就相当于编译器生成的那个delegate
      

  7.   

    当然要写成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。
      

  8.   

    既然不用省事的方法写,那么当然就要用费事的方法调用。有的时候我们写烂代码不是因为学的太少了,可能是因为学的太多了并且一知半解,于是纠结。.net的控件之所以会那样写,根本不是你这个模式。而如果你要按照普通的模式来在c#中使用Event,写public event EventHandler ValueChanged;就足够了。
      

  9.   

    不论你使用哪一种事件编程方式,总之你要调用最终的EvengHandler。当你写你的那种 add/remove 方式的时候,你怎么可能调用执行 ValueChanged 呢?因为它根本没有返回 EventHandler的功能,而只有 add/remove功能。所以你当然需要调用 onValueChanged 这个目标 EvengHandler。
      

  10.   

    我明白了。就是要另外添加一个字典之类的集合来保存eventhandler来实现这个功能。哈哈,谢谢各位大大的解说。