传递封装类中的事件

时间:2014-01-02 10:26:53

标签: c# events encapsulation

如果我有一个封装了B类实例的A类,是否可以通过A类实例传递一个在B类中引发的事件?例如:

public classB
{
    ...
    public event EventArgs SomeEvent;
    protected virtual void OnSomeEvent(EventArgs e)
    ...
}

public classA
{
    ...
    private classB = new ClassB();
    ...
}

我想要发生的是A类的任何实例也暴露SomeEvent,这样当B类引发它被A类引发时?

有人可以提供帮助或建议吗?

2 个答案:

答案 0 :(得分:3)

对于简单的类,没有像routed events这样的东西。当B级引发事件时,您应该订阅A类事件并从Class中引发事件:

public class ClassA
{
    public event EventHandler SomeEvent = (s,e) => { };
    private ClassB classB = new ClassB();

    public ClassA()
    {
       classB.SomeEvent += (s,e) => SomeEvent(this, e);
    }    
}

更经典的方式:

public ClassA
{
    public event EventHandler SomeEvent;
    private ClassB classB = new ClassB();

    public ClassA()
    {
       classB.SomeEvent += ClassB_SomeEvent;
    }

    private void ClassB_SomeEvent(object sender, EventArgs e)
    {
        if (SomeEvent != null)
            SomeEvent(this, e);
    }
}

答案 1 :(得分:2)

另一个选择是将事件委托给原始类:

public class ClassA
{
    private ClassB classB = new ClassB();
    public event EventHandler SomeEvent
    {
        add
        {
            classB.SomeEvent += value;
        }
        remove
        {
            classB.SomeEvent -= value;
        }
    }
}

这意味着当事件在ClassB中引发时,ClassA.SomeEvent的所有订阅者也会收到通知,因为他们实际上订阅了ClassB.SomeEvent。我不确定这是否是你真正想要的,但无论如何,你总是可以使用subscribe-and-raise方法。

虽然有一个问题:sender对象将是ClassB的实例,而不是ClassA,这意味着您无法将事件委托给,例如,WPF使用INotifyDataErrorInfo验证,其中视图模型本身预计会引发验证事件。然后你只需要订阅并加注。