help creating an MRU menu

flynn

Regular
Joined
Jul 28, 2005
Messages
59
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.
Code:
 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:
	// 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)
 
Parameter type EventHandler

You could make the BuildMRUSection function take a parameter of type EventHandler, and then call it like so:

C#:
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:
 
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?
 
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?
 
EventHandler parameter

Your function would now become:

C#:
public void BuildMRUSection(ref ToolStripMenuItem MRUMenuItem_Recent, EventHandler clickHandler)
{
    //...
    tsmi.Click += clickHandler;
    //...
}

And called like so:

C#:
mruDynamic.BuildMRUSection(ref MRUMenuItem_Recent, new EventHandler(OnMRURecentItemClick));

Good luck :cool:
 
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!
 
Back
Top