0

I am trying to assign an event handler that uses an event argument that extends System.EventArgs to a ToolStripMenuItem. When I enter the name of the handler it wants to create an event handler that uses System.EventArgs. This is for a list of recent files.

Here is the code

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

Any help with this will be greatly appreciated.

leppie
  • 115,091
  • 17
  • 196
  • 297
Tom Magaro
  • 181
  • 3
  • 13
  • The event is fired by the ToolStripMenuItem, and that one does not "know" about the FileName property, so how should it be able to fire an event with RecentEventArgs? – LInsoDeTeh Jul 08 '15 at 08:46
  • I am inheriting from the EventArgs class and extending it with the FileName property, and using it in the event handler – Tom Magaro Jul 08 '15 at 13:16

1 Answers1

0

You are heading in the right direction but you missed some key parts. Keep in mind that everything in c# is strongly typed which means that all method signatures can't change their any of their arguments at runtime. This also true for delegates (that is what you're using if you are subscribing to events).

As you already have your custom EventArgs, what is still missing is a delegate that describes the method signature your new event (because that is what you're after) will be calling.

// the public delegate with the custom eventargs
public delegate void RecentEventHandler(object sender, RecentEventArgs e);

Now you want something that acts as a ToolStripMenuItem but fires the Recent event is it gets clicked and send your custom eventargs as the payload. Let's create a subclass to handle that logic:

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

In the above class I override the default OnClick handler to invoke any subscribers to the Recent event where we create a new RecentEventArgs. Notice the Recent delegate of type RecentEventHandler.

With this bits working we need to bring our class into play.

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

Here we see that we add a new instance of the RecentFileMenuItem with a filename in the constructor to the recent list. The Show method matches the signature and so we can subscribe to the Recent event with the delegate pointing to that method.

rene
  • 41,474
  • 78
  • 114
  • 152