如何实现C#事件处理?

时间:2012-03-27 20:54:30

标签: c# event-handling

使用赋值运算符更新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) {}

5 个答案:

答案 0 :(得分:7)

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;

答案 1 :(得分:6)

事件完全取决于它的作用,但我认为事件就像属性一样 - 除了getter和setter之外,你有add和{{1}每个动作都会让代表订阅或取消订阅活动。

C#中的字段式事件使用委托字段实现事件,并修复了添加/删除实现 - 有点像自动实现的属性。但您可以在removeadd处理程序中执行任何操作。

有关详细信息,请参阅我的article on delegates and events

至于数据源本身 - 它没有分配字段 - 它分配给属性,所以再次,它可以做任何想做的事情,包括提高remove事件。

答案 2 :(得分:6)

它并不完全清楚你在问什么。如果您正在询问属性设置器如何执行某些操作:属性设置器是一种方法。它像任何其他方法一样工作。在这种情况下,当调用属性setter时,它会检查是否需要引发事件,如果是,则会引发事件。

如果你问的是事件本身是如何实现的,Jon的文章当然很棒。如果您正在寻找有关如何在C#中实现事件的其他技术分析,以及实施如何随时间发生变化,请参阅Chris Burrows&#39;关于该主题的博客文章:

http://blogs.msdn.com/b/cburrows/archive/tags/events/

从底部开始。

Chris是开发人员,他为编译器的语义分析和代码生成设计并实现了很多变化。

答案 3 :(得分:0)

Datasource是一个属性,并在集合中调用事件处理程序。

您可以使用ilspy查看实际实现方式。

答案 4 :(得分:-1)

事件处理程序在内部调用,因为提供事件的类(在本例中为DataGridView)在其代码中的某个位置显式触发事件。 DataSource的属性设置器听起来像是触发此特定事件的适当位置,尽管我没有查看源代码以确切地进行验证。

我建议查找一个关于如何为另一个类提供自己的事件的简单教程。它可以让您更好地了解事件提供者如何在没有太多细节的情况下工作。