none
Change backcolor and forecolor when hovering menu items of MenuStrip RRS feed

  • Question

  • Hello,

    That´s my question. I have no clue how to change forecolor of items when hovering them. I change color when hovering but forecolor is the same before hovering so I can´t see it. I would like to change it.

    This is the snippet code I´m using to configure my MenuStrip:

    this

     

    .MainMenuStrip = menuStrip1;

     

    //Add a menu.
    MyMenuItemPrincipal menuItem = new MyMenuItemPrincipal();
    menuItem.Text =
    "Prueba";
    menuItem.Width = 100;
    menuItem.BackColor =
    Color.Transparent;
    menuItem.ForeColor =
    Color.White;
    menuItem.Font =
    new Font(this.Font, FontStyle.Bold);
    this.MainMenuStrip.Items.Add(menuItem);

    //Add a sub menu.
    MyMenuItemSecundario subItem = new MyMenuItemSecundario();
    subItem.BackColor =
    Color.FromArgb(243,245,192);
    subItem.ForeColor =
    Color.FromArgb(72, 72, 61);
    subItem.Text =
    "Open";
    menuItem.DropDownItems.Add(subItem);

    //Add a menu.
    MyMenuItemPrincipal menuItem = new MyMenuItemPrincipal();
    menuItem.Text =
    "Prueba";
    menuItem.Width = 100;
    menuItem.BackColor =
    Color.Transparent;
    menuItem.ForeColor =
    Color.White;
    menuItem.Font =
    new Font(this.Font, FontStyle.Bold);
    this.MainMenuStrip.Items.Add(menuItem);

    //Add a sub menu.
    MyMenuItemSecundario subItem = new MyMenuItemSecundario();
    subItem.BackColor =
    Color.FromArgb(243,245,192);
    subItem.ForeColor =
    Color.FromArgb(72, 72, 61);
    subItem.Text =
    "Open";
    menuItem.DropDownItems.Add(subItem);

     

    MyMenuItemSecundario subItem = new MyMenuItemSecundario();
    subItem.BackColor =
    Color.FromArgb(243,245,192);
    subItem.ForeColor =
    Color.FromArgb(72, 72, 61);
    subItem.Text = "Open";
    menuItem.DropDownItems.Add(subItem);

    public

     

    class MyMenuItemPrincipal : ToolStripMenuItem
    {
    protected override void OnPaint(PaintEventArgs e)
    {
    base.OnPaint(e);
    if (this.Selected)
    {
    SolidBrush a = new SolidBrush(Color.FromArgb(243,245,192));
    e.Graphics.FillRectangle(a, e.ClipRectangle);
    Rectangle rect = e.ClipRectangle;
    rect.X += 100;
    rect.Width -= 100;
    StringFormat sf = new StringFormat();
    sf.LineAlignment =
    StringAlignment.Center;
    Font b = new Font(this.Font,FontStyle.Bold);
    e.Graphics.DrawString(
    this.Text, b, Brushes.White, rect, sf);
    }
    }

    public class MyMenuItemSecundario : ToolStripMenuItem
    {
    protected override void OnPaint(PaintEventArgs e)
    {
    base.OnPaint(e);
    if (this.Selected)
    {
    SolidBrush a = new SolidBrush(Color.FromArgb(243, 245, 192));
    //e.Graphics.FillRectangle(Brushes.Transparent, e.ClipRectangle);
    Rectangle rect = e.ClipRectangle;
    rect.X += 100;
    rect.Width -= 100;
    StringFormat sf = new StringFormat();
    sf.LineAlignment =
    StringAlignment.Center;
    e.Graphics.DrawString(
    this.Text, this.Font, Brushes.Red, rect, sf);
    }
    }
    }

     

    Could you help me?It´s really important to get this.

    My other question is: in the same MenuStrip I have the a menu item and this one has a item son. When opening the main item (dad) to access to the son item, the background color of the main item is a bright blue. I would like to know how to change this too.

    Thank you in advance, I hope you can help me.

    Greetings,
    egurre_egurre

    Thursday, September 17, 2009 3:58 PM

Answers

  • This is most easily done by providing your own renderer.  For example:

        public partial class Form1 : Form {
            public Form1() {
                InitializeComponent();
                menuStrip1.Renderer = new MyRenderer();
            }
            private class MyRenderer : ToolStripProfessionalRenderer {
                protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs e) {
                    if (!e.Item.Selected) base.OnRenderMenuItemBackground(e);
                    else {
                        Rectangle rc = new Rectangle(Point.Empty, e.Item.Size);
                        e.Graphics.FillRectangle(Brushes.Beige, rc);
                        e.Graphics.DrawRectangle(Pens.Black, 1, 0, rc.Width - 2, rc.Height - 1);
                    }
                }
            }
        }
    }

    Hans Passant.
    • Proposed as answer by Kira Qian Tuesday, September 22, 2009 6:39 AM
    • Marked as answer by Kira Qian Wednesday, September 23, 2009 8:12 AM
    • Unmarked as answer by Microsoft rules Thursday, September 24, 2009 10:18 AM
    • Marked as answer by nobugzModerator Thursday, September 24, 2009 11:50 AM
    • Unmarked as answer by Microsoft rules Monday, September 28, 2009 9:06 AM
    • Marked as answer by nobugzModerator Sunday, October 4, 2009 4:20 PM
    Thursday, September 17, 2009 5:50 PM
    Moderator

All replies

  • This is most easily done by providing your own renderer.  For example:

        public partial class Form1 : Form {
            public Form1() {
                InitializeComponent();
                menuStrip1.Renderer = new MyRenderer();
            }
            private class MyRenderer : ToolStripProfessionalRenderer {
                protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs e) {
                    if (!e.Item.Selected) base.OnRenderMenuItemBackground(e);
                    else {
                        Rectangle rc = new Rectangle(Point.Empty, e.Item.Size);
                        e.Graphics.FillRectangle(Brushes.Beige, rc);
                        e.Graphics.DrawRectangle(Pens.Black, 1, 0, rc.Width - 2, rc.Height - 1);
                    }
                }
            }
        }
    }

    Hans Passant.
    • Proposed as answer by Kira Qian Tuesday, September 22, 2009 6:39 AM
    • Marked as answer by Kira Qian Wednesday, September 23, 2009 8:12 AM
    • Unmarked as answer by Microsoft rules Thursday, September 24, 2009 10:18 AM
    • Marked as answer by nobugzModerator Thursday, September 24, 2009 11:50 AM
    • Unmarked as answer by Microsoft rules Monday, September 28, 2009 9:06 AM
    • Marked as answer by nobugzModerator Sunday, October 4, 2009 4:20 PM
    Thursday, September 17, 2009 5:50 PM
    Moderator
  • Thank you for your reply Hans.

    I have implemented your code but still doesn´t fix my problem. When hovering doesn´t change forecolor (backColor it does) of main menu and submenu. Hover works ok, but I need to change foreColor because hover color is similar to foreColor.

    The other thing is when main menu item is expanded to show submenu items. If I hover a submenu item, the selected item of main menu to show submenu has a bright blue color. 

    I need to get this somehow, I would be very grateful if you could help me.
    Thursday, September 24, 2009 10:41 AM
  • I showed you what is needed, it is up to you to override more of the methods to get it the way you want it.

    Hans Passant.
    Thursday, September 24, 2009 11:50 AM
    Moderator
  • Thanks so much Hans! Ive been looking on google for some time now and youre method is explained so easy! :D
    I finnaly got my highlight color changed ;) Thanks

    Jordy Emond,
    Friday, September 25, 2009 12:52 PM
  • I showed you what is needed, it is up to you to override more of the methods to get it the way you want it.

    Hans Passant.

    I appreciate your help but I´m stuck on developing my own styles. I will be grateful if you could at least tell me how to change forecolor when hovering items. I have been developing for hours but I am not able to change it, that´s why I need a litle push because I see that I´m close to the solution.

    Thank you.
    Monday, September 28, 2009 9:06 AM
  • I changed the code a bit so that everything will changes colors now, the root of the buttons stayed windows color blue or something like that, but now everything is the color i wanted ;) also on hover.

    Here is the code:

    private

     

    class MyRenderer : ToolStripProfessionalRenderer

    {

     

    protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs e)

    {

     

    if (!e.Item.Selected)

    {

     

    Rectangle rc = new Rectangle(Point.Empty, e.Item.Size);

    e.Graphics.FillRectangle(

    Brushes.Red, rc);

    e.Graphics.DrawRectangle(

    Pens.Red, 1, 0, rc.Width - 2, rc.Height - 1);

    }

     

    else

    {

     

    Rectangle rc = new Rectangle(Point.Empty, e.Item.Size);

    e.Graphics.FillRectangle(

    Brushes.Gray, rc);

    e.Graphics.DrawRectangle(

    Pens.Gray, 1, 0, rc.Width - 2, rc.Height - 1);

    }

     

     

    }

    }





    Hope it helps ;)

    Greets

    Monday, September 28, 2009 12:45 PM
  • i was render but when i render menustrip after that i cant change menustrip child backcolor.
    Thursday, December 3, 2009 6:39 PM
  • Okay, This sounds like what I want.... I made a menu, and with that, the colors of it are... BackColor = Black, and ForeColor = Red... What I want is for when the user hovers over the menu items and clicks on them the Colors change to BackColor = Red and ForeColor = Black, then when the mouse leaves an item, it reverts back to original, BackColor = Black and ForeColor = Red.  I tried coding it like I know how to, and it didn't work, it just seemed to change the ForeColors... So please help me code this, thanks!
    Thursday, December 31, 2009 10:37 PM
  • Greetings, All!

    I came across this trying to find a clean way to override some of the OnRender events on a WinForms Tool Strip. This page seems a bit messy, and somewhat unclear to some. So I thought I would post my 2 cents, for clarity and completeness:

    The first thing you want to do is create your own Tool Strip Renderer, which inherits the ToolStripProfessionalRenderer:

    public class ToolStripWhateverNameRenderer : ToolStripProfessionalRenderer
        {
            public ToolStripFrameworkRenderer()
            {
    
            }
        }

    Go ahead and create a constructor (as good practice dictates). The next thing is to override some base event calls. If your looking to get rid of the unsightly borders around the tool strip, and create a flat appearance, then you'll want to override the OnRenderToolStripBorder call, and kill it (by doing nothing):

    protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e)
            {
                // DO NOT CALL BASE EVENT (DO NOTHING FOR NO BORDER)
            }

    To change the background, and foreground, of a menu items when the mouse hovers over it, you'll need to override the OnRenderMenuItemBackground call, and substitute your own colors for the graphics elements:

    protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs e)
            {
    
                if (!e.Item.Selected)
                {
                    e.Item.ForeColor = Color.DarkGray;
                    base.OnRenderMenuItemBackground(e);
                }
                else
                {
                    Pen oPen = new Pen(Color.FromArgb(75, 75, 75));
                    SolidBrush oBrsh = new SolidBrush(Color.FromArgb(75, 75, 75));
                    
                    e.Item.ForeColor = Color.FromArgb(26, 157, 196);
                    Rectangle rc = new Rectangle(Point.Empty, e.Item.Size);
                    e.Graphics.FillRectangle(oBrsh, rc);
                    e.Graphics.DrawRectangle(oPen, 0, 0, rc.Width, rc.Height);
    
                    oPen.Dispose();
                    oBrsh.Dispose();
                }
            }

    The oPen and oBrsh objects are replacements for the native Pen and Brush objects. This is necessary if you want to specify a custom color. If you want to use a native color, just use the native color properties of those objects (i.e. Pen.Red, or Brush.White). You will notice that I set a color in the !e.Item.Selected section, before calling the base event method. This is because whenever you change the foreground of a menu item, it remains that color until it is changed again. Meaning that when a mouse hovers the menu item, and you change the foreground in addition to the background, you must ensure the foreground is changed back when the mouse leaves the items boundaries. So be sure to change the color back to whatever it's set to normally.

    Also note, that if you do use a custom Pen or Brush, you need to properly dispose of them afterwards. The intellisense will show you the property descriptions, so I won't go into what the parameters do in the FillRectangle and DrawRectangle methods. It should be pretty self explanatory.

    Now, in order to use your custom renderer, you must set the Renderer property of the affected tool strip, in your forms constructor directly after the InitializeComponent() method call:

    public mdiYourFormName()
            {
    
                InitializeComponent();
    
                // Set Menu & Status Strip to your custom renderer
                this.menuMyMainMenu.Renderer = new ToolStripWhateverNameRenderer();
                this.statMyStatusStrip.Renderer = new ToolStripWhateverNameRenderer();
    
    
            }
    This assumes your using a Status Strip at the bottom. If not, just omit that line. The result of this, should give you a nice (flat) Tool Strip (and Status Strip) with your own mouse over effects. Hope this helps to clarify things.

    Have a Great Day!



    Thursday, August 2, 2018 5:33 PM