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.
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:
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)