Search code examples
c#winformstoolstripcontextmenustrip

Change transparency for ToolStrip submenu


I am tampering with ToolStrip modifications as of now and is trying to make the submenu also transparent like the MenuStrip. I can't manage to make the submenu's property to be like the menu itself.

How do I do that?

Here's my code for the modifications:

    public class ArrowRenderer : ToolStripProfessionalRenderer
    {
        public ArrowRenderer() : base(new LeftMenuColorTable())
        {

        }
        protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e)
        {
            var tsMenuItem = e.Item as ToolStripMenuItem;
            if (tsMenuItem != null)
                e.TextColor = Color.White;
            base.OnRenderItemText(e);
        }

        protected override void OnRenderArrow(ToolStripArrowRenderEventArgs e)
        {
            var tsMenuItem = e.Item as ToolStripMenuItem;
            if (tsMenuItem != null)
                e.ArrowColor = Color.White;
            base.OnRenderArrow(e);
        }
        protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs e)
        {
            var tsMenuItem = e.Item as ToolStripMenuItem;
            if (tsMenuItem != null)
                e.Item.BackColor = Color.Black;
            base.OnRenderMenuItemBackground(e);
        }
    }
    public class LeftMenuColorTable : ProfessionalColorTable
    { 
        public override Color MenuItemSelected
        {
            // when the menu is selected
            get { return ColorTranslator.FromHtml("#494f52");  }
        }

        public override Color ToolStripBorder
        {
            get { return ColorTranslator.FromHtml("#FFFFFF"); }
        }
        public override Color ToolStripDropDownBackground
        {
            get { return Color.White; }
        }
    }

    internal void SetTrayMenu()
    {
        if (m_menu != null)
            if (notifyIcon.ContextMenuStrip != null)
                notifyIcon.ContextMenuStrip.Refresh();

        m_menu = new ContextMenuStrip();
        m_menu.Renderer = new ArrowRenderer();
        m_menu.AllowTransparency = true;
        m_menu.Opacity = 0.8;

        m_menu.BackColor = Color.Black;
}

enter image description here


Solution

  • Because the ToolStripDropDownMenu that hosts/lists the sub items or DropDownItems is not the same object that the ContextMenuStrip inherits. Hence you need to apply the same settings for each sub menu or DropDown.

    The SetTrayMenu() should do:

    internal void SetTrayMenu()
    {
        if (m_menu != null && notifyIcon.ContextMenuStrip != null)
            //Why?
            notifyIcon.ContextMenuStrip.Refresh();
        else
        {
            m_menu = new ContextMenuStrip
            {
                Renderer = new ArrowRenderer(),
                AllowTransparency = true,
                Opacity = 0.8,
            };
    
            foreach (var dd in m_menu.Items.OfType<ToolStripMenuItem>()
                .Where(x => x.HasDropDown))
            {
                var ddm = dd.DropDown as ToolStripDropDownMenu;
    
                if (ddm != null)
                {
                    ddm.AllowTransparency = true;
                    ddm.Opacity = 0.8;
                }
            }
    
            m_menu.BackColor = Color.Black;
        }
    }
    

    Before

    SOQ61911652A

    After

    SOQ61911652

    Note: Opacity = 0.5 here.