事件与委托简介
自C# 1.0开始,界面编程时,我们就可以通过使用 += 实现与方法的关联。如我们需要点击按钮 btnClose
关闭窗体时,可以使用以下代码:
btnClose.Click += new System.EventHandler(btnClose_Click);
其中,所要调用的 btnClose_Click
方法是一个标准方法,定义如下所示。
private void btn_Click(object o, System.EventArgs j)
{
Close();
}
在早期的代码中都是这么编写,后来随着 C# 3.0 的 Lambda 语法的引入,最终在VS2015开始,关联代码变得更加简洁,索性省去了事件委托,直接与方法名关联:
btnClose.Click += btnClose_Click;
事件的Lambda写法
请先看一下以下代码,这是实际项目中直接使用的一段代码。
private void InitializeDGV(DataGridViewX dgv)
{
string oldValue = null;
dgv.CellBeginEdit += (sender, e) => oldValue = (sender as DataGridView).Value.ToString();
dgv.CellEndEdit += (sender, e) =>
{
DataGridViewCell editCell = dgv.Rows[dgv.CurrentCell.RowIndex].Cells[1];
if(editCell.Value.ToString() != oldValue)
doSomething();
};
}
可以看到,我们直接将事件与对应的事件方法使用 Lambda 表达式关联。比如,可以直接使用 => 进行关联,如 dgv.CellBeginEdit += (sender, e) => oldValue = (sender as DataGridView).Value.ToString();
语法非常简洁。如果有多条语句,则使用大括号括起来即可。
作用域
在这个函数中,我们定义了 CellBeginEdit 和 CellEndEdit 两个事件的处理函数。在这两个函数中,我们可以发现,定义了一个变量 oldValue
用于记录原值,然后当值在编辑后如果发生变化,则做相应的处理。这里我们可以发现,虽然 oldValue
一个函数级变量,但是它的作用域实际上是对象级的。因为在实际的应用中,开始编辑和结束编辑这两个事件发生后,都会对其进行调用,且调用的结果都会有变化。换言之,如果仅是函数内级变量,应该其只能是第一次赋值时的值,以后不会再发生变化。所以这点要特别注意。