不确定跨多个类的事件/委托的实际实现

本文关键字:实现 事件 不确定 | 更新日期: 2023-09-27 18:16:17

我已经阅读了这里关于事件和委托的几页,并理解了它们背后的思想,但不确定如何在多个类中使用它们。到目前为止,我只是依赖IDE为我设置一切,我没有意识到它只在一个类中工作。

public class MyForm : Form
{
    public MyForm()
    {
        ...
        this.Controls.Add(menuBuilder.GenerateMenuForMyForm());
        //load other controls into the form to visualize/manipulate data
    }
    public void UpdateDataInControls()
    {
        //reloads info into controls based on data in serializable class.
    }
}

public class MenuBuilder
{
    public MenuStrip GenerateMenuForMyForm()
    {
        MenuStrip menu = new MenuStrip();
        ...
        ToolStripMenuItem loadfile = new ToolStripMenuItem();
        loadfile.name = "loadfile";
        loadfile.text = "Load File";
        loadfile.Click += new EventHandler(loadfile_Click);
        file.DropDownItems.Add(loadfile);
        ...
        return menu;
    }
    void loadfile_Click(object sender, EventArgs e)
    {
        //Open a file dialog and deserialize file
        //Need to send an event to MyForm letting it know that it needs to 
        //update controls in the form to reflect the deserialized data.
    }
}

所以在这种情况下,我有一个类内的事件工作,但我不确定如何设置的东西,所以MyForm可以从MenuBuilder接收事件。我试过像

loadfile.Click += new EventHandler(myFormObject.loadfile_Click);

并在MyForm中创建loadfile_Click()函数,但这似乎与通过事件本身驱动功能的想法相违背,因为它需要将表单的对象本身传递给构造函数。如果是这种情况,我不妨直接调用该函数。

不确定跨多个类的事件/委托的实际实现

这里有一个简单的方法来实现你所寻找的。这是一个基本的事件模型,一个类声明它的事件,一个观察者类订阅它。

using System;
using System.Windows.Forms;
public class MyForm : Form
{
    public MyForm()
    {
        var menuBuilder = new MenuBuilder();
        menuBuilder.FileLoaded += (sender, args) => UpdateDataInControls();
        Controls.Add(menuBuilder.GenerateMenuForMyForm());
        //load other controls into the form to visualize/manipulate data
    }
    public void UpdateDataInControls()
    {
        //reloads info into controls based on data in serializable class.
    }
}
internal class FileLoadedEventArgs : EventArgs
{
    // customize event arguments if need be
    // e.g. public string FileName {get;set;}
}
public class MenuBuilder
{
    // declare event delegate 
    internal delegate void FileLoadedEvent(object sender, FileLoadedEventArgs e);
    // declare event for observers to subscribe 
    internal event  FileLoadedEvent FileLoaded;
    public MenuStrip GenerateMenuForMyForm()
    {
        MenuStrip menu = new MenuStrip();
        /*
        ToolStripMenuItem loadfile = new ToolStripMenuItem();
        loadfile.name = "loadfile";
        loadfile.text = "Load File";
        loadfile.Click += new EventHandler(loadfile_Click);
        file.DropDownItems.Add(loadfile);
        */
        return menu;
    }
    void loadfile_Click(object sender, EventArgs e)
    {   
        // fire the event
        FileLoaded(this, new FileLoadedEventArgs());
    }
}