C#事件处理是如何实现的
本文关键字:实现 何实现 事件处理 | 更新日期: 2023-09-27 18:29:15
使用赋值运算符更新DataGridView.DataSource
时,会调用DataSourceChanged
事件处理程序。您不能在C#中重载赋值操作,那么如何在内部调用事件处理程序呢?
public void foo(){
this.dataGridView.DataSourceChanged += new EventHandler(bar);
this.dataGridView.DataSource = dt;
}
//this handler is called after datasource changes
private void bar(object sender, EventArgs e) {}
DataSource
实现为一个属性。
private object _dataSource;
public object DataSource {
get
{
return _dataSource;
}
set
{
if (value != _dataSource) {
_dataSource = value;
UpdateTheDataGridView();
RaiseTheDataSourceChangedEvent();
}
}
}
读/写属性是一组两个方法,当您访问该属性时会自动调用它们;分配值时为set
,读取属性时为get
。
另外请注意,只有当您为数据源分配了不同的内容时,才会注册更改。这意味着您无法通过重新分配相同的数据源来刷新网格。
var list = new List<string> { "a", "b", "c" };
dgv.DataSource = list;
list.Add("d");
dgv.DataSource = list; // Does not work.
解决方法:
list.Add("d");
dgv.DataSource = null; // <== this does the trick.
dgv.DataSource = list;
您要问什么还不完全清楚。如果你在问属性设置器如何做某事:属性设置器是一个方法。它的工作原理和其他任何方法一样。在这种情况下,当调用属性setter时,它会检查是否需要引发事件,如果需要,则引发事件。
如果你问事件本身是如何实现的,Jon的文章当然很好。如果您正在寻找关于事件如何在C#中实现以及实现如何随时间变化的附加技术分析,请参阅Chris Burrows关于以下主题的博客文章:
http://blogs.msdn.com/b/cburrows/archive/tags/events/
从底部开始。
Chris是开发人员,他设计并实现了对编译器的语义分析和代码生成的许多更改。
它的作用完全取决于事件,但我认为事件就像属性一样——除了有add
和remove
操作,而不是getter和setter,每个操作都接受委托来订阅或取消订阅事件。
C#中类似事件的字段使用委托的字段来实现事件,并修复了添加/删除实现——有点像自动实现的属性。但是您可以在add
或remove
处理程序中执行任何您喜欢的操作。
有关更多信息,请参阅我关于代表和活动的文章。
至于数据源本身——它不是分配字段——它是分配给属性,所以,它可以做任何它想做的事情,包括引发DataSourceChanged
事件。
数据源是一个属性,在集合中调用事件处理程序。
您可以使用ilspy来查看这是如何实际实现的。
事件处理程序在内部被调用,因为提供事件的类(在本例中为DataGridView
)在其代码中的某个点显式激发事件。DataSource
的属性setter听起来像是激发这个特定事件的合适位置,尽管我没有在源代码中查看以进行确切验证。
我建议查阅一个简单的教程,了解如何为另一个班级提供自己的活动。它将让你更好地了解事件的提供者需要如何工作,而不需要太多的细节。