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

时间:2014-08-04 02:38:52

标签: c#

我在这里阅读了几个关于事件和代理的页面,并理解它们背后的想法,但不确定如何在多个类中使用它们。到现在为止,我只是依靠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()函数,但这似乎与通过事件本身驱动功能的想法相反,因为它需要将表单的对象本身传递给构造函数。如果是这种情况,我不妨直接调用该函数。

1 个答案:

答案 0 :(得分:0)

这是实现您所需要的一种简单方法。它是一个基本事件模型,其中一个类声明了它的事件,一个观察者类订阅了它。

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());
    }
}