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

WPF系统托盘NotifyIcon如何适配深色/浅色模式修改右键菜单背景

NotifyIcon 深浅模式适配方案

你当前使用的是System.Windows.Forms.NotifyIcon控件,它的默认右键菜单属于WinForms原生控件,不会自动适配WPF的主题体系,可通过以下两种方案实现深浅模式适配:

方案1:自定义WinForms菜单绘制(无需额外引入组件)

手动开启上下文菜单的自绘模式,根据当前深浅模式配置绘制样式:

  • 初始化时为NotifyIcon绑定支持自绘的上下文菜单
_notifyIcon = new Forms.NotifyIcon();
_notifyIcon.Icon = MySystray.Resources.Systray_icon;
_notifyIcon.Text = APP_NAME;

// 新增上下文菜单配置
var contextMenu = new Forms.ContextMenu();
contextMenu.OwnerDraw = true; // 开启自定义绘制
contextMenu.MeasureItem += ContextMenu_MeasureItem;
contextMenu.DrawItem += ContextMenu_DrawItem;

// 按需添加菜单项示例
contextMenu.MenuItems.Add("打开主窗口", (s,e)=>{ /* 业务逻辑 */ });
contextMenu.MenuItems.Add("退出", (s,e)=>{ /* 业务逻辑 */ });

_notifyIcon.ContextMenu = contextMenu;
  • 实现测量和绘制事件,适配深浅模式
// 自行维护当前深浅模式状态,可通过Win32 API获取系统主题或跟随应用自身设置
private bool _isDarkMode;

private void ContextMenu_MeasureItem(object sender, Forms.MeasureItemEventArgs e)
{
    // 自定义菜单项尺寸
    e.ItemHeight = 24;
    e.ItemWidth = 160;
}

private void ContextMenu_DrawItem(object sender, Forms.DrawItemEventArgs e)
{
    // 按深浅模式配置颜色
    var bgColor = _isDarkMode ? Color.FromArgb(38, 38, 38) : Color.White;
    var textColor = _isDarkMode ? Color.White : Color.Black;
    var hoverBgColor = _isDarkMode ? Color.FromArgb(55, 55, 55) : Color.FromArgb(204, 232, 255);

    // 绘制背景
    var useBg = (e.State & Forms.DrawItemState.Selected) != 0 ? hoverBgColor : bgColor;
    e.Graphics.FillRectangle(new SolidBrush(useBg), e.Bounds);

    // 绘制文字
    var currentItem = ((Forms.ContextMenu)sender).MenuItems[e.Index];
    e.Graphics.DrawString(currentItem.Text, e.Font, new SolidBrush(textColor), e.Bounds.Left + 24, e.Bounds.Top + 2);
}
  • 监听系统主题变化或应用主题切换事件,更新_isDarkMode值后重建/刷新上下文菜单即可。

方案2:弹出WPF原生ContextMenu(适配成本更低,样式更统一)

放弃WinForms原生菜单,右键点击时直接弹出已经做好深浅模式适配的WPF上下文菜单,可完全复用WPF的样式体系:

_notifyIcon.MouseClick += (s, e) =>
{
    if (e.Button != Forms.MouseButtons.Right) return;
    
    // 直接使用你WPF项目中已经适配好深浅模式的ContextMenu,可直接从资源字典加载
    var wpfMenu = new System.Windows.Controls.ContextMenu();
    wpfMenu.Items.Add(new System.Windows.Controls.MenuItem { Header = "打开主窗口" });
    wpfMenu.Items.Add(new System.Windows.Controls.MenuItem { Header = "退出" });

    // 定位到鼠标位置弹出
    wpfMenu.Placement = System.Windows.Controls.Primitives.PlacementMode.MousePoint;
    wpfMenu.IsOpen = true;
};

提示:此方案无需处理WinForms控件的绘制逻辑,只需要保证WPF的ContextMenu已经和应用其他控件共用一套深浅模式样式即可,整体样式一致性更高。

内容的提问来源于stack exchange,提问作者Rajib_119

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 02:36:04