You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# WinForms:动态重写ToolStripProfessionalRenderer设置菜单项文本颜色

解决C# WinForms动态设置菜单项文本颜色的问题

先解释构造函数的作用

你的SkinRenderer构造函数是调用父类ToolStripProfessionalRenderer的构造方法,传入自定义MenuColorTable——父类会基于这个颜色表渲染菜单的背景、边框、分隔线等基础样式;你额外加的Console.WriteLine("test")只是构造实例时的测试输出。

动态设置文本颜色的两种实现方法

因为SkinRenderer是Form1的嵌套类,可以通过以下方式访问Form的变量,实现条件化颜色设置:

方法1:用委托回调解耦(推荐)

给SkinRenderer添加一个委托属性,用来动态获取文本颜色,避免直接依赖Form实例:

private class SkinRenderer : ToolStripProfessionalRenderer
{
    // 定义回调委托,用于动态获取文本颜色
    public Func<Color> TextColorProvider { get; set; }

    public SkinRenderer(MenuColorTable colorTable) : base(colorTable) { }

    protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e)
    {
        // 优先使用回调返回的颜色,无回调则用默认值
        e.TextColor = TextColorProvider?.Invoke() ?? Color.FromArgb(220, 220, 220);
        // 调用父类方法完成文本渲染,不要自己调用TextRenderer.DrawText,避免样式冲突
        base.OnRenderItemText(e);
    }
}

在Form1的加载事件中初始化渲染器,并绑定回调:

// Form1的字段,示例条件变量
private int intVariable = 12;

private void Form1_Load(object sender, EventArgs e)
{
    var skinRenderer = new SkinRenderer(new MenuColorTable());
    // 绑定颜色逻辑:根据intVariable的值返回对应颜色
    skinRenderer.TextColorProvider = () => 
    {
        return intVariable > 10 ? Color.Red : Color.FromArgb(220, 220, 220);
    };
    menu.Renderer = skinRenderer;
}

当intVariable变化时,调用menu.Invalidate()触发菜单重绘,颜色会自动更新:

// 比如修改变量后触发重绘
intVariable = 8;
menu.Invalidate();

方法2:直接引用Form实例(简单直接)

利用嵌套类可访问外部类私有成员的特性,在SkinRenderer中持有Form1的引用:

private class SkinRenderer : ToolStripProfessionalRenderer
{
    private readonly Form1 _form;

    public SkinRenderer(MenuColorTable colorTable, Form1 form) : base(colorTable)
    {
        _form = form;
    }

    protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e)
    {
        // 直接访问Form的变量判断条件
        e.TextColor = _form.intVariable > 10 ? Color.Red : Color.FromArgb(220, 220, 220);
        base.OnRenderItemText(e);
    }
}

Form1加载时初始化:

menu.Renderer = new SkinRenderer(new MenuColorTable(), this);

同样,变量变化后调用menu.Invalidate()更新渲染。

内容的提问来源于stack exchange,提问作者Roberto D V Leonardo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 06:33:27