views:

172

answers:

3

I have a System.Windows.Form class (my main class). There is a RootMenu object. This is my own custom object. I'm trying to loop through the RootMenu object and on each pass add a ToolStripMenuItem to a ContextMenuStrip (which I named ContextMenu). The RootMenu object contains a List. Links have Names and Urls (both strings).

When the form loads my "Factory" class loads me up a RootMenu object, which I then pass into the ProcessMenu method.

Code Excerpt Here:

    private void ProcessMenu(RootMenu rm)
    {
        foreach (var lnk in rm.Links)
        {
            var tsmi = new ToolStripMenuItem(lnk.Name, null, new EventHandler(Navigate));
            tsmi.ToolTipText = lnk.Url;
            ContextMenu.Items.Add(tsmi);
        }
    }
    private void Navigate(object sender, EventArgs e)
    {
        var tsmi = (ToolStripMenuItem) sender;
        System.Diagnostics.Process.Start(tsmi.ToolTipText);
    }

Do you see how I have to store the lnk.Url in the ToolTipText? In the VB6 days all the controls had the "tag" property. You used to be able to stuff extra stuff into the control that you would need later on. I don't want to use the tooltip for this, but what are my alternatives? Storing all the Urls in a Hash/Dictionary using the name as a key? I may not always have unique names, so I would like to avoid this route. What is the proper way to handle this in .NET? Maybe I missing some basic concept I have never been exposed to.

+4  A: 

ToolStripMenuItem has a Tag property:

tsmi.Tag = lnk.Url;

In fact, quite a few Windows Forms controls have it.

How the heck did I miss that... Is that the best pattern for this issue?
tyndall
+3  A: 

Just inherit the old class and stick a Tag property in there:

public class myToolStripMenuItem : ToolStripMenuItem
{
    public object myTag { get; set; }
}
Charlie Somerville
same comment I made to Bill. +1
tyndall
It's probably the best option rather than stuffing info into the tag. You can be more descriptive in what the extra property contain, and if you need to store more data, it's easier and faster to add another property rather than serializing/unserializing data in Tag
Charlie Somerville
+2  A: 

Create your own object inheriting from ToolStripMenuItem and add any custom properties....

    private void ProcessMenu(RootMenu rm)
    {
        foreach (var lnk in rm.Links)
        {
            var tsmi = new UrlToolStripMenuItem(lnk.Name, null, new EventHandler(Navigate))
            {
                Url = lnk.Url,
            };
            ContextMenu.Items.Add(tsmi);
        }
    }
    private void Navigate(object sender, EventArgs e)
    {
        var tsmi = (UrlToolStripMenuItem)sender;
        System.Diagnostics.Process.Start(tsmi.Url);
    }

    public class UrlToolStripMenuItem : ToolStripMenuItem
    {
        public UrlToolStripMenuItem(string text, Image image, EventHandler onClick) : base(text, image, onClick)
        {
        }

        public string Url { get; set; }
    }
Bill
I thought of this on the way home. Not ideal but does the trick. +1
tyndall