public delegate void SomeHandler(object sender, System.EventArgs e);
/**
public Control()
{
//这里使用的delegate必须与事件中声名的一致
}
public void RaiseSomeEvent()
{
EventArgs e = new EventArgs();
Console.Write("Please input 'a':");
string s = Console.ReadLine();
//在用户输入一个小a的情况下触发事件,否则不触发
{
SomeEvent(this, e);
}
}
//事件的触发者自己对事件进行处理,这个方法的参数必须和代理中声名的一致
{
Console.WriteLine("hello");
}
}
private void ProcessSomeEvent(object sender, EventArgs e) if (s == "a") this.SomeEvent += new SomeHandler(this.ProcessSomeEvent); //this.SomeEvent += new System.EventHandler(this.Control_SomeEvent); public event SomeHandler SomeEvent; //public event System.EventHandler SomeEvent; */ * 如果需要在事件的参数中使用自己定义的类型,也要自己定义delegate
* 可以采用系统提供的System.EventHandler, 这里为了说明情况使用了自己定义的delegate
public class Control
///</summary>
/// 事件的触发者
///<summary>
事件的接收者:
{
private Control ctrl = new Control();
public Container()
{
//这里使用的delegate必须与事件中声名的一致
ctrl.SomeEvent += new Control.SomeHandler(this.ResponseSomeEvent);
ctrl.RaiseSomeEvent();
}
public static void Main()
{
Container pane = new Container();
//这个readline是暂停程序用的,否则画面会一闪而过什么也看不见
Console.ReadLine();
}
//这是事件的接受者对事件的响应
{
Console.WriteLine("Some event occur!");
}
}
private void ResponseSomeEvent(object sender, EventArgs e) //ctrl.SomeEvent += new EventHandler(this.OnSomeEvent);class Container///</summary>/// 事件的接收和处理者///<summary> |
程序运行的结果如下:
please input 'a':a
hello
Some event occur!
事件的应用
例如有下面的需求需要实现:程序主画面中弹出一个子窗口。此时主画面仍然可以接收用户的操作(子窗口是非模态的)。子窗口上进行某些操作,根据操作的结果要在主画面上显示不同的数据。我发现一些程序员这样实现这个功能:
主画面弹出子窗口后,将自己的指针交给子画面,然后在子画面中使用这个指针,调用主画面提供的方法,改变主画面上的数据显示。这样虽然可以达到目的,但是各个模块之间产生了很强的耦合。一般说来模块之间的调用应该是单方向的:模块A调用了模块B,模块B就不应该反向调用A,否则就破坏了程序的层次,加强了耦合程度,也使得功能的改变和追加变得很困难。
这时正确的做法应该是在子窗口的操作过程中发出各种事件,而由主窗口捕捉这些事件进行处理,各个模块专心的做自己的事情,不需要过问其他模块的事情。