Seth
Seth

Reputation: 1835

C# How to change MenuItem's text in the OnClick

I am trying to change the text of a MenuItem inside a ContextMenu. I thought I have done this before, but I cannot remember.

Here is what I have:

private void TrayIcon_Click(object sender, EventArgs e)
        {
            MessageBox.Show(((MenuItem)sender).Text);
            if(((MenuItem)sender).Text.Equals("Pause"))
            { 
                icon.ContextMenu.MenuItems[0].Text = "Unpause";
                shouldPause = true;
            }

            if(((MenuItem)sender).Text.Equals("Unpause"))
            {
                icon.ContextMenu.MenuItems[0].Text = "Pause";
                shouldPause = false;
            }

            if(((MenuItem)sender).Text.Equals("Exit"))
            {
                icon.Visible = false;
                Application.Exit();
            }
        }

When I try to change "Pause" to "Unpause" it doesn't work. However, if I try to change "Pause" to "Pizza", it actually works.. What the heck..

Thanks all!

EDIT:

Changed my code to the following:

private void TrayIcon_Click(object sender, EventArgs e)
        {
            if(((MenuItem)sender).Text.Equals("Pause"))
            {
                shouldPause = true;
            }

            if(((MenuItem)sender).Text.Equals("Unpause"))
            {
                shouldPause = false;
            }

            if(((MenuItem)sender).Text.Equals("Exit"))
            {
                icon.Visible = false;
                Application.Exit();
            }
            string text = "Pause";

            if(shouldPause)
            {
                text = "Unpause";
            }
            icon.ContextMenu.MenuItems[0].Text = text;
        }

And now it works.

Was it because I was trying to change the text on the item too soon after being clicked?

Upvotes: 1

Views: 1302

Answers (1)

poke
poke

Reputation: 388333

Based on your observation, I am assuming that icon.ContextMenu.MenuItems[0] and (MenuItem)sender are the same menu item.

That would explain why it didn’t work with your first code:

if(((MenuItem)sender).Text.Equals("Pause"))
{ 
    icon.ContextMenu.MenuItems[0].Text = "Unpause";
    shouldPause = true;
}

if(((MenuItem)sender).Text.Equals("Unpause"))
{
    icon.ContextMenu.MenuItems[0].Text = "Pause";
    shouldPause = false;
}

The problem becomes a bit more clear when you introduce local variables:

var senderItem = (MenuItem)sender;
var firstItem = icon.ContextMenu.MenuItems[0];

if(senderItem.Text.Equals("Pause"))
{ 
    firstItem.Text = "Unpause";
    shouldPause = true;
}

if(senderItem.Text.Equals("Unpause"))
{
    firstItem.Text = "Pause";
    shouldPause = false;
}

If now senderItem and firstItem are the same, then what this code does is the following:

  1. Check if the text is Pause
  2. Change the text to Unpause
  3. Set shouldPause to true
  4. Check if the text is Unpause
  5. Change the text to Pause
  6. Set shouldPause to false

So basically, since these are separate ifs, they both run, with the second overwriting the first.

You can generally avoid this by using else if instead of multiple separate/unliked if:

if(senderItem.Text.Equals("Pause"))
{ 
    firstItem.Text = "Unpause";
    shouldPause = true;
}
else if(senderItem.Text.Equals("Unpause"))
{
    firstItem.Text = "Pause";
    shouldPause = false;
}

Now, only one of those branches will ever run.

Upvotes: 3

Related Questions