Event handler for context menu; help needed

J

james

Hello,
I am having a little trouble creating an event handler for a context menu
toolstripmenuitem.

I've seen various tutorials and so on, but I keep getting a bit stuck!
So far I have a second class defining the eventargs I want to use:

public class ApptEventArgs : EventArgs{
public int ApptUID;
public String ApptOp;
public int RowID;
public int ColID;
}

In my Forms class, I have declared an event:

public delegate void ApptEventHandler(object sender, ApptEventArgs e);


Then I have created a function to put the code in for when the event fires:

public void NewApptEvent(object sender, ApptEventArgs e)
{
MessageBox.Show("NEW Event Fired");
}


Finally, I am constructing the menu and trying the following to set the
arguments and configure my event to be used:

ApptEventArgs NewApptArgs = new ApptEventArgs();
NewApptArgs.ApptOp = "NEW";
NewApptArgs.ApptUID = 0;
NewApptArgs.ColID = ColIdx;
NewApptArgs.RowID = RowIdx;
//Create Menu Items
ToolStripMenuItem NewItem = new ToolStripMenuItem("New
Appointment",global::Itinerary.Properties.Resources.NewAppt, new
ApptEventHandler(NewApptEvent(this,NewApptArgs)));
.......

When I compile, I get several errors, all on the last line where I am
configuring the new toolstrip item.
I get:

"Method Name expected"
"The best overloaded method for ...ToolStripMenuItem(string,
System.Drawing.Image, System.EventHandler) has some invalid arguments"
"Argument 3: Cannot convert from <project>.ApptEventHandler' to
'System.EventHandler'"


Any ideas?
I have tried various different ways of doing this but I always end up with
some or all of the above errors. I'm obviously not getting it!

At the end of the day, my Context Menu has about 5 main menus that pop out
submenus dynamically created depending on where you clicked, and I need to
fire off an event with those 4 parameters passed to it.

James.
 
C

Chris Jobson

james said:
Hello,
I am having a little trouble creating an event handler for a context menu
toolstripmenuitem.

I've seen various tutorials and so on, but I keep getting a bit stuck!
So far I have a second class defining the eventargs I want to use:

public class ApptEventArgs : EventArgs{
public int ApptUID;
public String ApptOp;
public int RowID;
public int ColID;
}

In my Forms class, I have declared an event:

public delegate void ApptEventHandler(object sender, ApptEventArgs e);


Then I have created a function to put the code in for when the event
fires:

public void NewApptEvent(object sender, ApptEventArgs e)
{
MessageBox.Show("NEW Event Fired");
}


Finally, I am constructing the menu and trying the following to set the
arguments and configure my event to be used:

ApptEventArgs NewApptArgs = new ApptEventArgs();
NewApptArgs.ApptOp = "NEW";
NewApptArgs.ApptUID = 0;
NewApptArgs.ColID = ColIdx;
NewApptArgs.RowID = RowIdx;
//Create Menu Items
ToolStripMenuItem NewItem = new ToolStripMenuItem("New
Appointment",global::Itinerary.Properties.Resources.NewAppt, new
ApptEventHandler(NewApptEvent(this,NewApptArgs)));
......

When I compile, I get several errors, all on the last line where I am
configuring the new toolstrip item.
I get:

"Method Name expected"
"The best overloaded method for ...ToolStripMenuItem(string,
System.Drawing.Image, System.EventHandler) has some invalid arguments"
"Argument 3: Cannot convert from <project>.ApptEventHandler' to
'System.EventHandler'"


Any ideas?
I have tried various different ways of doing this but I always end up with
some or all of the above errors. I'm obviously not getting it!

At the end of the day, my Context Menu has about 5 main menus that pop out
submenus dynamically created depending on where you clicked, and I need to
fire off an event with those 4 parameters passed to it.

I think the problem is that you cannot control the type of event handler
that the ToolStripMenuItem will use when it's clicked - it is defined as
using a System.EventHandler and so the method you provide as the third
argument to the constructor must be one. Thus when you create the item the
code is:
ToolStripMenuItem NewItem = new ToolStripMenuItem("New Appointment",
global::Itinerary.Properties.Resources.NewAppt,
new EventHandler(MyEventHandler));

where MyEventhandler is defined as:
private void MyEventHandler(Object sender, EventArgs e)
{
...
}

If, as a result of the click, you need to do something using 4 parameters
then you have at least two options:
(1) Assign a different event handler to each menu item, and hard-code the
appropriate 4 values in it (and you can of course raise another event from
within your event handler if that's what you really want to do).
(2) Use the same event handler for all the menu items, and use the Sender
parameter to identify which menu item was actually clicked and hence what
values should be used for the 4 parameters.

Hope this helps.
Chris Jobson
 
J

JamesB

Chris Jobson said:
I think the problem is that you cannot control the type of event handler
that the ToolStripMenuItem will use when it's clicked - it is defined as
using a System.EventHandler and so the method you provide as the third
argument to the constructor must be one. Thus when you create the item the
code is:
ToolStripMenuItem NewItem = new ToolStripMenuItem("New Appointment",
global::Itinerary.Properties.Resources.NewAppt,
new EventHandler(MyEventHandler));

where MyEventhandler is defined as:
private void MyEventHandler(Object sender, EventArgs e)
{
...
}

If, as a result of the click, you need to do something using 4 parameters
then you have at least two options:
(1) Assign a different event handler to each menu item, and hard-code the
appropriate 4 values in it (and you can of course raise another event from
within your event handler if that's what you really want to do).
(2) Use the same event handler for all the menu items, and use the Sender
parameter to identify which menu item was actually clicked and hence what
values should be used for the 4 parameters.

Hope this helps.
Chris Jobson

Hi Chris,
It sounds helpful - I'll know when I get into work tomorrow!
Thanks,
James
 
J

james

Chris Jobson said:
If, as a result of the click, you need to do something using 4 parameters
then you have at least two options:
(1) Assign a different event handler to each menu item, and hard-code the
appropriate 4 values in it (and you can of course raise another event from
within your event handler if that's what you really want to do).
(2) Use the same event handler for all the menu items, and use the Sender
parameter to identify which menu item was actually clicked and hence what
values should be used for the 4 parameters.

Hi,
OK, I managed to make a "normal" event get fired fine (object sender,
EventArgs e) but I couldn't see how to get my parameters into the sender
object... Hard coding didn't seem right as the parameters would vary
depending on what was right-clicked... in any case, I actually solved it
another way, but I would like to know how or why it works as I don't
entirely understand.

I added a second event handler that would use my ApptEventArgs class:

void NewApptEventHandler(object sender, ApptEventArgs e)
{
//do stuff here with e.<param>
}

And when I create my menu, I do it with the following bit of code:

ToolStripMenuItem MDSubItem = new ToolStripMenuItem("blah", null );
MDSubItem.Text = ApptDetail; //Item from datareader
MDSubItem.Tag = mnuApptUID; //Item from datareader
MDSubItem.Click += delegate {NewApptEventHandler(this, MDApptArgs);};
//MDApptArgs is an instance of my EventArgs class with the parameters for
this record
MoveDate.DropDownItems.Add(MDSubItem); //Add the item to the menu

It's the delegate line I don't get.
In my original post I had the delegate line outside my forms class as
examples showed and so on, but the error was basically that it couldn't
convert "my" event handler to a system.eventhandler, yet with the above, it
works!
My theory is that what I am doing here is adding a "second" event handler to
the click event of the menu item and this can be any sort of event handler?
And the "default" click event (which doesn't technically exist, but
whatever) is still the original?

As I said, it works a treat so I'm not too fussed, but I would like to
actually know why it works!

James.
 
C

Chris Jobson

james said:
OK, I managed to make a "normal" event get fired fine (object sender,
EventArgs e) but I couldn't see how to get my parameters into the sender
object... Hard coding didn't seem right as the parameters would vary
depending on what was right-clicked... in any case, I actually solved it
another way, but I would like to know how or why it works as I don't
entirely understand.

I added a second event handler that would use my ApptEventArgs class:

void NewApptEventHandler(object sender, ApptEventArgs e)
{
//do stuff here with e.<param>
}

And when I create my menu, I do it with the following bit of code:

ToolStripMenuItem MDSubItem = new ToolStripMenuItem("blah", null );
MDSubItem.Text = ApptDetail; //Item from datareader
MDSubItem.Tag = mnuApptUID; //Item from datareader
MDSubItem.Click += delegate {NewApptEventHandler(this, MDApptArgs);};
//MDApptArgs is an instance of my EventArgs class with the parameters for
this record
MoveDate.DropDownItems.Add(MDSubItem); //Add the item to the menu

It's the delegate line I don't get.

I like your solution! I hadn't thought of it, but it seems to be a very good
way of getting the results you want. I find understanding what goes on
behind the scenes with events and delegates rather confusing myself, but
what I think is happening here (and I'm waiting for someone who knows better
to correct me!) is that the line:
MDSubItem.Click += delegate {NewApptEventHandler(this, MDApptArgs);};
effectively creates a hidden System.EventHandler method (i.e. one with the
signature "object sender, EventArgs e") that is called through the
MDSubItem's Click event, and this hidden method then calls your
NewApptEventHandler with the right parameters.

Chris Jobson
 
C

Chris Jobson

james said:
OK, I managed to make a "normal" event get fired fine (object sender,
EventArgs e) but I couldn't see how to get my parameters into the sender
object... Hard coding didn't seem right as the parameters would vary
depending on what was right-clicked... in any case, I actually solved it
another way, but I would like to know how or why it works as I don't
entirely understand.

I added a second event handler that would use my ApptEventArgs class:

void NewApptEventHandler(object sender, ApptEventArgs e)
{
//do stuff here with e.<param>
}

And when I create my menu, I do it with the following bit of code:

ToolStripMenuItem MDSubItem = new ToolStripMenuItem("blah", null );
MDSubItem.Text = ApptDetail; //Item from datareader
MDSubItem.Tag = mnuApptUID; //Item from datareader
MDSubItem.Click += delegate {NewApptEventHandler(this, MDApptArgs);};
//MDApptArgs is an instance of my EventArgs class with the parameters for
this record
MoveDate.DropDownItems.Add(MDSubItem); //Add the item to the menu

It's the delegate line I don't get.

I like your solution! I hadn't thought of it, but it seems to be a very good
way of getting the results you want. I find understanding what goes on
behind the scenes with events and delegates rather confusing myself, but
what I think is happening here (and I'm waiting for someone who knows better
to correct me!) is that the line:
MDSubItem.Click += delegate {NewApptEventHandler(this, MDApptArgs);};
effectively creates a hidden System.EventHandler method (i.e. one with the
signature "object sender, EventArgs e") that is called through the
MDSubItem's Click event, and this hidden method then calls your
NewApptEventHandler with the right parameters.

Chris Jobson
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top