C#仅将事件引发到继承的类

时间:2014-10-17 09:35:58

标签: c# winforms event-handling

我有一个通用的用户控件:

public partial class SearchBoxGeneric<T> : UserControl
{
    protected class RecordFoundEventArgs
    {
        public T Record { get; private set; }

        public RecordFoundEventArgs(T record)
        {
            this.Record = record;
        }
    }
    protected event EventHandler<RecordFoundEventArgs> RecordFound;

    //Called from search button
    public void Find()
    {
        //1. Search for record in the db
        //2. Raise event to derived classes
    }
}

我有从这个通用控件继承的用户控件。现在,当我从数据库中搜索记录时,我想将事件提升到继承的控件。

我该怎么做?

2 个答案:

答案 0 :(得分:2)

要举起活动,您可以使用与公共活动相同的代码:

public void Find()
{
    T record = FindRecordCore();
    if (record != default(T))
    {
        var recordFound = RecordFound;
        if (recordFound != null)
            recordFound(this, new RecordFoundEventArgs(record));
    }
}

要关注事件的正常模式,您应该添加特定的OnXyz方法:

protected virtual void OnRecordFound(RecordFoundEventArgs e)
{
    var recordFound = RecordFound;
    if (recordFound != null)
        recordFound(this, e);
}

像这样调用:

public void Find()
{
    T record = FindRecordCore();
    if (record != default(T))
        OnRecordFound(new RecordFoundEventArgs(record));
}

但是我会考虑的是,如果需要这样的事件。你为什么不简单地使用受保护的方法?事件是外部类的通知(或连接点),派生类总是可以简单地覆盖类方法。 protected事件是 strange ,您应该问问自己原因:

protected virtual void OnRecordFound(T record)
{
    // Derived classes will handle "event" here
}

public void Find()
{
    T record = FindRecordCore();
    if (record != default(T))
        OnRecordFound(record);
}

即使事件是public,如果您按照正常事件模式(并且您有protected OnRecordFound方法),通常派生类应该覆盖OnRecordFound()和事件{ {1}}由外部实体使用。

答案 1 :(得分:0)

通常会触发事件,以便在发生某些事情时通知其他人。

public class SearchBox {
    public event EventHandler<RecordFoundEventArgs> RecordFound;

    protected virtual void OnRecordFound(RecordFoundEventArgs e) {
        var recordFound = RecordFound;
        if (recordFound != null) {
            recordFound(this, e);
        }
    }

    public void Find() {
        // ...

        // Fire event
        OnRecordFound(new RecordFoundEventArgs(...));
    }
}

// Usage
var searchBox = new SearchBox();
searchBox.RecordFound += (s, e) => { ... };
searchBox.Find();   // trigger the eventhandler we just defined

但是如果你有一个派生类,更常见的是覆盖OnRecordFound方法,并添加你在那里运行所需的逻辑。

public class SpecialSearchBox: SearchBox {
    protected override void OnRecordFound(RecordFoundEventArgs e) {
        base.OnRecordFound(e);

        // Do something extra
    }
}

现在每当触发事件时,派生类中的逻辑都会自动运行。

如果您已定义事件只是为了通知派生类,那么定义一个可以从基类调用的虚方法可能更容易。