通过类C#传递事件

时间:2017-10-13 23:47:30

标签: c# wpf class events

我有一个第一堂课,当发生一些变化时会引发一个事件:

public class MyFirstClass {
    public event EventHandler ChangesHappened;

    public MyFirstClass() {

    }

    public void MyMethod() {
        //Thing happened

        ChangesHappened?.Invoke(this, new EventArgs());
    }
}

我还有第二个类,它有一个FirstClass列表:

public class MySecondClass {
    private List<MyFirstClass> first;

    public MySecondClass() {
        foreach(var f in first) {
            first.Changed += (s, e) => {};
        }
    }
}

最后我有一个带有SecondClass实例的WPF应用程序。如何从WPF处理Changed事件(FirstClass)?我应该在SecondClass中创建一个事件并在first.Changed += (s, e) => { NewEvent(this, new EventArgs()); }内提升它,然后在WPF中捕获它吗?

目标是在WPF应用程序中获取Changed事件。

3 个答案:

答案 0 :(得分:1)

在我看来,这是最简单的答案:

public class MySecondClass
{
    public event EventHandler ChangesHappened;
    private List<MyFirstClass> first;

    public MySecondClass()
    {
        foreach (var f in first)
        {
            f.ChangesHappened += (s, e) => ChangesHappened?.Invoke(s, e);
        }
    }
}

答案 1 :(得分:1)

另一种选择是使用Microsoft的Reactive Framework,它允许您将事件(良好的可观察性)作为一流的语言公民传递。

你可以这样做:

void Main()
{
    var msc = new MySecondClass();

    msc.Changes.Subscribe(ep =>
    {
        /* Do stuff with
            ep.Sender
            ep.EventArgs
                from the `MyFirstClass` instances
        */
    });
}

public class MyFirstClass
{
    public event EventHandler ChangesHappened;
    public IObservable<EventPattern<EventArgs>> Changes;

    public MyFirstClass()
    {
        this.Changes = Observable.FromEventPattern<EventHandler, EventArgs>(
            h => this.ChangesHappened += h, h => this.ChangesHappened += h);
    }

    public void MyMethod()
    {
        ChangesHappened?.Invoke(this, new EventArgs());
    }
}

public class MySecondClass
{
    public IObservable<EventPattern<EventArgs>> Changes;

    private List<MyFirstClass> first = new List<MyFirstClass>();

    public MySecondClass()
    {
        this.Changes = first.Select(f => f.Changes).Merge();
    }
}

答案 2 :(得分:0)

正如@Enigmativity已经提到的:当你有一个类时,必须管理其他类(一堆MyFirstClass引用),那么你必须将你的事件从子类转发到manager类。

public class MySecondClass
{
    public event EventHandler Changed;
    private List<MyFirstClass> firstClassList;

    public MySecondClass()
    {
        firstClassList = new List<MyFirstClass>();
    }

    public void AddMyFirstClassList(List<MyFirstClass> firstClassList)
    {
        foreach (var firstClass in firstClassList)
            AddMyFirstClass(firstClass);
    }

    public void AddMyFirstClass(MyFirstClass firstClass)
    {
        // from sub class to manager class
        firstClass.Changed += firstClass_Changed;
        firstClassList.Add(firstClass);
    }

    private void firstClass_Changed(object sender, EventArgs args)
    {
        Changed?.Invoke(sender, args);
    }

    public void RemoveMyFirstClass(MyFirstClass firstClass)
    {
        MyFirstClass.Remove -= firstClass_Changed;
        firstClassList.Remove(firstClass);
    }
}

另一种选择是传递回调函数。你应该避免这种情况,除非你需要它明确:

public class MyFirstClass
{
    EventHandler handler;

    public MyFirstClass(EventHandler handler)
    {
        this.handler = handler;
    }

    public void MyMethod()
    {
        handler?.Invoke(this, new EventArgs());
    }
}

public class MySecondClass
{
    private List<MyFirstClass> firstClassList;

    public MySecondClass()
    {
        firstClassList = new List<MyFirstClass>();
    }

    // you have instantiated your class and passed your callback function previously.
    public void AddMyFirstClass(MyFirstClass firstClass)
    {
        firstClassList.Add(firstClass);
    }

    // for demonstrating the instantiation.
    public void AddMyFirstClass(EventHandler handler)
    {
        firstClassList.Add(new MyFirstClass(handler));
    }
}