flynn Posted July 8, 2008 Posted July 8, 2008 I am trying to create a generic class that will take a most-recently-used list and create a context menu for it. The code below (in a slightly different version) works perfect, but only if I have the function "BuildMRUSection()" in the CustomerClass. The reason for this is because the "tsmi.Click += " needs to be able to see the "OnMRURecentItemClick" event handler in order to assign it. What I need to be able to do is pass a pointer to the function "OnMRURecentItemClick" into the MRUList_Dynamic class in order to do the assignment within that class. This will make the routine more encapsulated and easier for the caller. public partial class CustomerClass { MRUList_Dynamic mruDynamic = new MRUList_Dynamic(); private void OnMouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Right) { MRUList_Dynamic mruDynamic = new MRUList_Dynamic(); mruDynamic.BuildMRUSection(ref MRUMenuItem_Recent); <-- need to be able to pass a function pointer here in order to wire up the mru menu items to the event ((TextBox)sender).ContextMenuStrip = cmMRUList; } } // event handler for all mru menu items clicked private void OnMRURecentItemClick(object sender, EventArgs e) { ToolStripMenuItem tsmi = (ToolStripMenuItem)sender; if (tsmi.Equals(MRUMenuItem_Copy)) Clipboard.SetDataObject(tbxCustomerName.SelectedText); else if (tsmi.Equals(MRUMenuItem_Cut)) { Clipboard.SetDataObject(tbxCustomerName.SelectedText); tbxCustomerName.SelectedText = ""; } else if (tsmi.Equals(MRUMenuItem_Paste)) ; else if (tsmi.Equals(MRUMenuItem_Delete)) tbxCustomerName.SelectedText = ""; else { // set the textboxes based on the mru item selected tbxCustomerName.Text = tsmi.Text; tbxCustomerNumber.Text = tsmi.Tag.ToString(); } } } public class MRUList_Dynamic { public const Int16 NUM_ITEMS = 10; const Byte NAME_COLUMN = 0; const Byte ID_COLUMN = 1; // array contains the "most recently used" items static String[,] MRUArray = new String[NUM_ITEMS, 2] { { "", "" }, { "", "" }, { "", "" }, { "", "" }, { "", "" }, { "", "" }, { "", "" }, { "", "" }, { "", "" }, { "", "" } }; // adds the name/PCN pair in the first slot, moving all other items down 1 slot public static void AddName(String PCN, String sName) { for (Int16 x = NUM_ITEMS - 1; x > 0; x--) { MRUArray[x, ID_COLUMN] = MRUArray[x - 1, ID_COLUMN]; MRUArray[x, NAME_COLUMN] = MRUArray[x - 1, NAME_COLUMN]; } MRUArray[0, NAME_COLUMN] = sName; MRUArray[0, ID_COLUMN] = PCN; } // retrieve the Name at a specific slot public static String GetNameAt(Int16 x) { return MRUArray[x, NAME_COLUMN]; } // retrieve the PCN at a specific slot public static String GetPcnAt(Int16 x) { return MRUArray[x, ID_COLUMN]; } // pass in the pop-up menu as a reference; then create the mru items public void BuildMRUSection(ref ToolStripMenuItem MRUMenuItem_Recent) { // if the dropdown menu items aren't cleared out, items might be duplicated over and over MRUMenuItem_Recent.DropDownItems.Clear(); for (Int16 x = 0; x < NUM_ITEMS; x++) { ToolStripMenuItem tsmi = new ToolStripMenuItem(); if (tsmi.Text != "") { tsmi.Size = new System.Drawing.Size(245, 22); tsmi.Visible = true; tsmi.Click += new EventHandler(OnMRURecentItemClick); //<--- need pointer to "OnMRURecentItemClick" function passed into here MRUMenuItem_Recent.DropDownItems.Add(tsmi); } } } } I've also tried to pre-fill (in the calling class) a ToolStripMenuItem's Click method with the address of the function of the event handler, then pass this into "BuildMRUSection()" as a template to create the mru menu items, but that doesn't work either. // code to pass in a pre-filled "template" of the menu item mruDynamic.BuildMRUSection(ref MRUMenuItem_Recent, tsmi_tmp); public void BuildMRUSection(ref ToolStripMenuItem MRUMenuItem_Recent, ToolStripMenuItem item_template) Quote
MrPaul Posted July 8, 2008 Posted July 8, 2008 Parameter type EventHandler You could make the BuildMRUSection function take a parameter of type EventHandler, and then call it like so: mruDynamic.BuildMRUSection(ref MRUMenuItem_Recent, new EventHandler(OnMRURecentItemClick)); Also, I don't see why MRUMenuItem_Recent needs to be ref, as you're not setting the value of it anywhere in the method. Good luck :cool: Quote Never trouble another for what you can do for yourself.
flynn Posted July 8, 2008 Author Posted July 8, 2008 When I type "new" to create the code you suggested, "new" doesn't display in the drop-down that is displayed (this is the closest match: "NewsStyleUriParser"). Am I missing something? Quote
Nate Bross Posted July 8, 2008 Posted July 8, 2008 You want to use the new keyword, as in declaring a new object as opposed to the TYPE of object. Did you try to copy/paste his code exactly? Quote ~Nate� ___________________________________________ Please use the [vb]/[cs] tags on posted code. Please post solutions you find somewhere else. Follow me on Twitter here.
MrPaul Posted July 8, 2008 Posted July 8, 2008 EventHandler parameter Your function would now become: public void BuildMRUSection(ref ToolStripMenuItem MRUMenuItem_Recent, EventHandler clickHandler) { //... tsmi.Click += clickHandler; //... } And called like so: mruDynamic.BuildMRUSection(ref MRUMenuItem_Recent, new EventHandler(OnMRURecentItemClick)); Good luck :cool: Quote Never trouble another for what you can do for yourself.
flynn Posted July 8, 2008 Author Posted July 8, 2008 Got it to work. Thanks Nate for your reply. A special thank you to MrPaul, this is exactly what I needed. MrPaul, I mis-read your original post and put the "new" in the definition instead of the method call, and of course the compiler was having none of that! Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.