C# 无法将单击事件分配给使用扩展eventargs参数的eventhandler

C# 无法将单击事件分配给使用扩展eventargs参数的eventhandler,c#,winforms,events,toolstripmenu,C#,Winforms,Events,Toolstripmenu,我正在尝试分配一个事件处理程序,该事件处理程序使用一个将System.EventArgs扩展到ToolStripMenuItem的事件参数。当我输入处理程序的名称时,它希望创建一个使用System.EventArgs的事件处理程序。这是最近文件的列表 这是密码 RecentEventArgs e = new RecentEventArgs(); e.FileName = item; ToolStripMenuItem recentItem = new ToolStripMenuItem(item

我正在尝试分配一个事件处理程序,该事件处理程序使用一个将System.EventArgs扩展到ToolStripMenuItem的事件参数。当我输入处理程序的名称时,它希望创建一个使用System.EventArgs的事件处理程序。这是最近文件的列表

这是密码

RecentEventArgs e = new RecentEventArgs();
e.FileName = item;
ToolStripMenuItem recentItem = new ToolStripMenuItem(item);
recentItem.Click += new EventHandler(RecentItem_Click);
mnuFileOpenRecentList.DropDownItems.Add(item);

private void RecentItem_Click(object sender, RecentEventArgs e)
{
    MessageManager.DisplayMessageBox("File -> Open Recent ->");
    OpenRecentFile(e.FileName);
    }

public class RecentEventArgs : EventArgs
{
    private string fileName;

    public RecentEventArgs()
        :base()
    {

    }

    public string FileName
    {
        get { return fileName; }
        set { fileName = value; }
    }
}

我们将非常感谢您的帮助。

您正朝着正确的方向前进,但错过了一些关键部分。请记住,c#中的所有内容都是强类型的,这意味着所有方法签名都不能在运行时更改其任何参数。这也适用于(如果您订阅的是事件,那么您使用的就是这个)

由于您已经有了自定义的EventArgs,所以仍然缺少一个委托,该委托描述了您的新事件(因为这正是您所追求的)将要调用的方法签名

// the public delegate with the custom eventargs
public delegate void RecentEventHandler(object sender, RecentEventArgs e);
现在,您需要一个充当ToolStripMenuItem的东西,但如果它被单击并将自定义eventargs作为有效负载发送,则会触发最近的事件。让我们创建一个子类来处理该逻辑:

public class RecentFileMenuItem:ToolStripMenuItem
{
    private string filename; // holds your path+file

    // constructur
    public RecentFileMenuItem(string filename)
        :base(Path.GetFileName(filename))
    {
        // keep our filename
        this.filename = filename;
    }

    // event delegate, subscribe to this
    public RecentEventHandler Recent;

    // click invokes all subscribers 
    // for the Recent Event
    protected override void OnClick(EventArgs e)
    {
        RecentEventHandler recent = Recent;
        if (recent !=null)
        {
            // create your RecentEventArgs here
            recent(this, new RecentEventArgs { FileName = filename });
        }
    }
}
在上面的类中,我重写了默认的OnClick处理程序来调用最近事件的任何订阅者,在最近的事件中我们创建了一个新的RecentEventArgs。注意
RecentEventHandler
类型的
Recent
委托

有了这些,我们需要让我们的班级发挥作用

    private void Form3_Load(object sender, EventArgs e)
    {
        RecentFileMenuItem recentItem = new RecentFileMenuItem("foo");

        mnuFileOpenRecentList.DropDownItems.Add(recentItem);

        recentItem.Recent += new RecentEventHandler(Show); 
    }

    // method signature that matches our RecentEventHandler delegate
    public void Show(object s, RecentEventArgs e)
    {
        MessageBox.Show(e.FileName);
    }

这里我们看到,我们在最近的列表中添加了
RecentFileMenuItem
的一个新实例,其构造函数中有一个文件名。
Show
方法与签名匹配,因此我们可以订阅
Recent
事件,委托指向该方法

该事件是由ToolStripMenuItem触发的,而该对象不“知道”FileName属性,因此它应该如何使用RecentEventTargets触发事件?我从EventArgs类继承并使用FileName属性扩展它,并在事件处理程序中使用它