I am creating a Context Menu Strip once a Rich Text Box is right clicked. There are 2 options, one to change the font and one to change the background color. However, once I click one of the menu options, the Context Menu Strip doesn’t close and overlays dialogs that are displayed. I know I can make it “global” and force it to close, but I would rather not. What is the best way to handle this?
// If the console is right clicked then show font options
private void rtb_console_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Right)
{
ContextMenuStrip menu = new ContextMenuStrip();
menu.Items.Add("Change Font");
menu.Items.Add("Change Background Color");
menu.Show(this, new Point(e.X, e.Y));
menu.ItemClicked += new ToolStripItemClickedEventHandler(menu_ItemClicked_ChangeFont);
}
}
// Determine whether to change the font or the font background color
void menu_ItemClicked_ChangeFont(object sender, ToolStripItemClickedEventArgs e)
{
Application.DoEvents(); // Read that this might help, but it doesn't
if (e.ClickedItem.Text == "Change Font")
{
FontDialog font = new FontDialog();
font.ShowColor = true;
font.Font = rtb_console.Font;
font.Color = rtb_console.ForeColor;
if (font.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
rtb_console.Font = font.Font;
rtb_console.ForeColor = font.Color;
}
}
else if (e.ClickedItem.Text == "Change Background Color")
{
ColorDialog color = new ColorDialog();
color.Color = rtb_console.BackColor;
if (color.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
rtb_console.BackColor = color.Color;
}
}
}
So this is what happens:

You don’t want to create the
ContextMenuStripand show it manually each time. The better way to do this is to create theContextMenuStriponce. Then assign it for theRichTextBoxby assigning it to theContextMenuStripproperty of theRichTextBox. Doing this, you will no longer need to manually launch theContextMenuStripeverytime a user clicks on it. It will occur automagically. It will also hide itself automagically in the way you would expect upon clicking on it.Do this once and then remove your event handler for the MouseUp event:
Also, please please please don’t use
Application.DoEvents();to try and force the UI to update itself. Head over to here and read the top answer. In general, if you are usingApplication.DoEvents(), you are doing something wrong and should considering changing your approach.One thing you may also consider doing, but it is really just a matter of preference… If you are using Visual Studio, consider creating you
ContextMenuStripin the designer. That way, you can add your items, icons, and individual callbacks for each item very easily and visually. Just something I like to do out of pure personal preference.