I am Showing a ContextMenu whenever the user right clicks on a specific location in a DataGridView.
I want the items of that ContextMenu to have a back color and fore color depending on their content.
How can I do this since ContextMenu has no back color or Fore color property?
I tried looking up ContextMenuStrip but this has to be connected to a ToolStripButton which I do not have and do not want.
In order to change the back color of a MenuItem you need to specify a draw item handler and set owner-draw to true for each item. Also for the color to actually take some space you need to implement a MeasureMenuItem handler.
So for example
color.MenuItems.Add(new MenuItem("#123456", menuHandler));
color.MenuItems.Add(new MenuItem("Green", menuHandler));
color.MenuItems.Add(new MenuItem("Red", menuHandler));
foreach (MenuItem item in color.MenuItems)
{
item.OwnerDraw = true;
item.DrawItem += item_DrawItem;
item.MeasureItem += MeasureMenuItem;
}
The above codes hooks up the items and their handlers.
void item_DrawItem(object sender, DrawItemEventArgs e)
{
MenuItem cmb = sender as MenuItem;
string color = SystemColors.Window.ToString();
if (e.Index > -1)
{
color = cmb.Text;
}
if (checkHtmlColor(color))
{
e.DrawBackground();
e.Graphics.FillRectangle(new SolidBrush(ColorTranslator.FromHtml(color)), e.Bounds);
e.Graphics.DrawString(color, new Font("Lucida Sans", 10), new SolidBrush(ColorTranslator.FromHtml(color)), e.Bounds);
}
}
The above code takes the MenuItem contents, converts it to a color, creates a rectangle for that color and draws it.
void MeasureMenuItem(object sender, MeasureItemEventArgs e)
{
MenuItem m = (MenuItem)sender;
Font font = new Font(Font.FontFamily, Font.Size, Font.Style);
SizeF sze = e.Graphics.MeasureString(m.Text, font);
e.ItemHeight = (int)sze.Height;
e.ItemWidth = (int)sze.Width;
}
And lastly the above few lines simply measure the area the MenuItem should take before drawing (basically measures the space of it's string content) so the draw_item handler knows how much space to take up
I allow myself to dig up the post because I've had the same problem (add background color to MenuItem in ContextMenu) and found this post. But the answer seemed very complicated. So I continued to search and find a simplet solution : Use ContextMenuStrip and ToolStripMenuItem Here is an example for users who has the same problem :
ContextMenuStrip cMenu=new ContextMenuStrip();
ToolStripMenuItem mi;
// Item 1, null in constructor to say : no picture on the label
mi=new ToolStripMenuItem("item 1",null , (s,a)=> actionOnClicItem1());
mi.BackColor = Color.Red;
cMenu.Items.add(mi);
// Separator
cMenu.Items.Add(new ToolStripSeparator());
// Item 2
mi=new ToolStripMenuItem("item 2",null , (s,a)=> actionOnClicItem2());
mi.BackColor = Color.Blue;
cMenu.Items.add(mi);
// show the context menu near by the mouse pointer
cMenu.Show(myDataGridView,new Point(e.X,e.Y));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With