1

I'm porting an old VB6 project to C#, using Winforms. The original uses DataDynamic's ActiveBar suite to manage changes to multiple items in toolbars, menus, and shortcut ribbons simultaneously. All the old code has to do to change the text of an item shared between several menus, a toolbar, and a context menu is change the "tool" object's "Caption" property.

I feel like .NET must have some way of sharing ToolStripItems between a variety of containers, but it doesn't look like it does. Am I missing something?

Currently I've started several times with a variety of ideas, from implementing a Clone extension method on ToolStripMenuItem objects and having my form keep track of each sharable. That failed when I realized that updating the local copy wouldn't update the others (I'd have to add complex updating events that is more work than simply turning each item on and off by hand). I've considered creating some way of updating all items based on its tag. That seemed pretty infeasible as well.

What techniques have y'all used in similar situations?

Chris Pfohl
  • 18,220
  • 9
  • 68
  • 111

2 Answers2

3

Well, this is actually one of the annoying limitations of .Net GUI-Building Libraries

A common workaround would be managing your Menus dynamically, adding Items to them as they are opening. Ugly but quite seamless from the user experience point of view. The trick is to use the following UI design pradigm : Menus are never displayed simultaneously, so you can hot-swap Items

private void myContextMenuStrip_Opening(object sender, CancelEventArgs e)
{
    myContextMenuStrip.Items.Insert(3, myToolStripMenuItem);
}  

Then using flags and code logic you would be able to know, As the Menu/ToolBar/ContextMenu is opened, what Items it should display.

Mehdi LAMRANI
  • 11,289
  • 14
  • 88
  • 130
  • "Menus are never displayed simultaneously" is not quite true given that we both have `Toolbar` categorized with `Menu` and `ContextMenu`. – Chris Pfohl Dec 01 '10 at 19:29
0

I wound up implementing a SharedMenuItem that's responsibility was to register and update the UI elements that needed change. The context menu wound up being different enough to warrant its own handler.

Instead of updating all the MenuItems I updated the SharedMenuItem which then took care of the other changes.

[EDIT] The code (adding other properties is trivial/automatically-generatable even):

public class SharedMenuItem
{
    bool enabled = false;
    public bool Enabled
    {
        get { return enabled; }
        set
        {
            enabled = value;
            foreach (var member in members)
            {
                member.Enabled = value;
            }
        }
    }

    bool visible;
    public bool Visible
    {
        get { return visible; }
        set
        {
            visible = value;
            foreach (var member in members)
            {
                member.Visible = visible;
            }
        }
    }

    string text;
    public string Text
    {
        get { return text; }
        set
        {
            text = value;
            foreach (var member in members)
            {
                member.Text = text;
            }
        }
    }

    string toolTipText = "";
    public string ToolTipText
    {
        get { return toolTipText; }
        set
        {
            toolTipText = value;
            foreach (var member in members)
            {
                member.ToolTipText = toolTipText;
            }
        }
    }

    private List<ToolStripItem> members = new List<ToolStripItem>();

    public void Remove(ToolStripItem member)
    {
        members.Remove(member);
    }

    public void Add(ToolStripItem member)
    {
        members.Add(member);
    }

    public SharedMenuItem(string text)
    {
        this.text = text;
    }
}
Chris Pfohl
  • 18,220
  • 9
  • 68
  • 111
  • However, from a design point of view, and technically speaking, Items in different menus -a fortiori shown simultaneously, ARE indeed different Items in you case, though pointing to the SAME action in final. – Mehdi LAMRANI Dec 04 '10 at 07:18
  • Yes, they're different items, but they need to share a set of properties at all times (a perfect "Observer" pattern opportunity which is *sort of* what the above is). – Chris Pfohl Dec 06 '10 at 12:46