views:

252

answers:

2

I have a ContextMenuStrip which displays items which can be named by the user; the user is allowed to give the items names containing ampersands. When the ContextMenuStrip is shown, the items' treat the ampersands as escape sequences, and underline the next character.

I could double up all the ampersands before I set the items' Text members, but that member is used elsewhere in the code so if possible, I'd like to stop the ContextMenuStrip from treating ampersands specially. Is there a way to turn that behaviour off?

+4  A: 

use && to display a single &

Edit: Sorry, I missed the second part of your question :(

You could always use string.Replace("&", "&&") on the text when you set it, but that seems messy.

Another alternative would be to inherit from ToolStripMenuItem and override the Set of the Text Property to replace & with &&. That would be a little better as it would keep the code in once place.

Pondidum
I could double up all the ampersands before I set the items' Text members, but that member is used elsewhere in the code so if possible, I'd like to stop the ContextMenuStrip from treating ampersands specially. Is there a way to turn that behaviour off?
Simon
You could have a second property you use in the binding which automagically escapes the ampersands for the ContextMenuStrip.
sixlettervariables
A: 

I don't think that there is any built in support for that (like the UseMnemonic property of the Button control), unfortunately. One way to do it is to make a brute-force method that will walk the control tree on the form and perform a replace on all ToolStripMenuItems found:

public TheForm()
{

    InitializeComponent();
    FixAmpersands(this.Controls);
}

private static void FixAmpersands(Control.ControlCollection controls)
{
    foreach (Control control in controls)
    {
        if (control is ToolStrip)
        {
            FixAmpersands((control as ToolStrip).Items);
        }
        if (control.Controls.Count > 0)
        {
            FixAmpersands(control.Controls);
        }
    }
}

private static void FixAmpersands(ToolStripItemCollection toolStripItems)
{
    foreach (ToolStripItem item in toolStripItems)
    {
        if (item is ToolStripMenuItem)
        {
            ToolStripMenuItem tsmi = (ToolStripMenuItem)item;
            tsmi.Text = tsmi.Text.Replace("&", "&&");
            if (tsmi.DropDownItems.Count > 0)
            {
                FixAmpersands(tsmi.DropDownItems);
            }
        }                
    }
}

This is, of course, useful primarily if the menu structure is not build up dynamically and occasionaly during the lifetime of the form. If new items are added every now and then you will probably need to run them through some method that will perform the ampersand-doubling at on a single item.

Fredrik Mörk