Изменить прозрачность для подменю ToolStrip

На данный момент я вмешиваюсь в модификации ToolStrip и пытаюсь сделать подменю прозрачным, как MenuStrip. У меня не получается сделать свойство подменю похожим на само меню.

Как я могу это сделать?

Вот мой код для модификаций:

    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;
}

введите здесь описание изображения


person TerribleDog    schedule 20.05.2020    source источник


Ответы (1)


Поскольку ToolStripDropDownMenu который содержит/списывает подэлементы или DropDownItems — это не тот же объект, что и ContextMenuStrip наследует. Следовательно, вам необходимо применить одни и те же настройки для каждого подменю или Раскрывающийся список.

SetTrayMenu() должен делать:

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;
    }
}

До

SOQ61911652A

После

SOQ61911652

Примечание. Непрозрачность здесь = 0,5.

person Community    schedule 20.05.2020
comment
Спасибо за ответ. Но как изменить цвет границы подменю? - person TerribleDog; 21.05.2020
comment
@TerribleDog Добро пожаловать, приятель. Вам также необходимо переопределить MenuBorder в классе LeftMenuColorTable. например public override Color MenuBorder => ColorTranslator.FromHtml("#FFFFFF"); - person ; 21.05.2020
comment
@TerribleDog Нет, это изменится. просто установите другой цвет, например Color.Red, чтобы увидеть. Что касается ToolStripSeparator, да, он игнорирует задний цвет. Вам нужно создать из него новый класс и вместо этого переопределить метод OnPaint. Проверьте это. Также вы можете создать новый класс из ToolStripMenuItem, чтобы рисовать что-то лучше. Я опубликовал что-то вроде это в этот контекст. Однако это VB.NET. Я верю, что вы можете справиться с этим :) - person ; 21.05.2020
comment
Да, спасибо за это, у меня были перекрывающиеся коды, которые мешали изменению, но есть еще один вопрос, imgur.com/ a/ZhPU2gj Как убрать границу слева? - person TerribleDog; 21.05.2020
comment
@TerribleDog Для этого требуется переопределить метод OnRenderToolStripBorder в классе ArrowRenderer, чтобы проверить, какой тип e.ToolStrip, и соответственно нарисовать e.AffectedBounds. например if (e.ToolStrip is ContextMenuStrip) { //draw the border }; else if (e.ToolStrip is ToolStripDropDownMenu) { }; else base.OnRenderToolStripBorder(e); и забудьте о переопределении свойства MenuBorder, как я упоминал выше. Возможно, вам придется уменьшить ширину и высоту прямоугольника e.AffectedBounds на 1. - person ; 21.05.2020
comment
Я сделал это с помощью ImageMarginGradientBegin. Большое спасибо - person TerribleDog; 21.05.2020
comment
@TerribleDog Добро пожаловать, приятель. Любое время. - person ; 21.05.2020