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

Xamarin Mac 如何实现点击窗口关闭按钮时最小化到托盘而非关闭?

点击窗口关闭按钮最小化到托盘实现方案

你要的Slack同款交互效果参考:
Slack交互示例动图

该功能的核心实现逻辑统一为:拦截窗口关闭事件,取消默认的销毁窗口/退出应用行为,将窗口隐藏/最小化,配合系统托盘图标实现入口留存,同时保留主动退出应用的入口避免应用无法正常关闭。

以下是常见开发技术栈的具体实现代码:

1. Electron(Slack本身基于该框架开发)

const { app, BrowserWindow, Tray, Menu, Notification } = require('electron')
let mainWindow
let tray
let isAppQuitting = false // 标记是否是主动退出应用

// 初始化主窗口
function createMainWindow() {
  mainWindow = new BrowserWindow({
    width: 900,
    height: 600,
    title: '你的应用名称'
  })
  mainWindow.loadFile('index.html')

  // 监听全局退出事件,区分主动退出和点关闭按钮
  app.on('before-quit', () => {
    isAppQuitting = true
  })

  // 核心:拦截窗口关闭事件
  mainWindow.on('close', (e) => {
    if (!isAppQuitting) {
      e.preventDefault()
      mainWindow.hide()
      // 可选:弹出系统通知提示用户
      new Notification({
        title: '应用已最小化',
        body: '可点击托盘图标重新打开窗口'
      }).show()
    }
  })
}

// 初始化系统托盘
function initTray() {
  tray = new Tray('你的托盘图标本地路径.png')
  const trayMenu = Menu.buildFromTemplate([
    {
      label: '打开主窗口',
      click: () => mainWindow.show()
    },
    {
      label: '退出应用',
      click: () => app.quit()
    }
  ])
  tray.setToolTip('你的应用名称')
  tray.setContextMenu(trayMenu)
  // 左键点击托盘直接打开窗口
  tray.on('click', () => mainWindow.show())
}

app.whenReady().then(() => {
  createMainWindow()
  initTray()
})

2. C# WPF

using System.Windows;
using System.Windows.Forms;
using System.Drawing;

public partial class MainWindow : Window
{
    private NotifyIcon _trayIcon;
    private bool _isInitiativeExit = false; // 标记是否主动触发退出

    public MainWindow()
    {
        InitializeComponent();
        // 初始化托盘配置
        _trayIcon = new NotifyIcon
        {
            Icon = new Icon("你的图标路径.ico"),
            Visible = true,
            Text = "你的应用名称"
        };
        // 托盘右键菜单
        var trayMenu = new ContextMenuStrip();
        trayMenu.Items.Add("打开主窗口", null, (s, e) => ShowMainWindow());
        trayMenu.Items.Add("退出应用", null, (s, e) =>
        {
            _isInitiativeExit = true;
            Close();
        });
        _trayIcon.ContextMenuStrip = trayMenu;
        // 双击托盘打开窗口
        _trayIcon.DoubleClick += (s, e) => ShowMainWindow();
    }

    // 重写关闭事件拦截逻辑
    protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
    {
        base.OnClosing(e);
        if (!_isInitiativeExit)
        {
            e.Cancel = true;
            Hide();
        }
        else
        {
            // 主动退出时销毁托盘资源
            _trayIcon.Dispose();
        }
    }

    private void ShowMainWindow()
    {
        Show();
        WindowState = WindowState.Normal;
        Activate();
    }
}

3. Qt

// mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QSystemTrayIcon>
#include <QMenu>
#include <QCloseEvent>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) {
        // 初始化托盘
        m_trayIcon = new QSystemTrayIcon(this);
        m_trayIcon->setIcon(QIcon(":/icons/tray_icon.png"));
        m_trayMenu = new QMenu(this);
        // 托盘菜单配置
        m_trayMenu->addAction("打开主窗口", this, &MainWindow::showNormal);
        m_trayMenu->addAction("退出应用", qApp, &QApplication::quit);
        m_trayIcon->setContextMenu(m_trayMenu);
        m_trayIcon->show();
        // 左键点击托盘切换窗口显隐
        connect(m_trayIcon, &QSystemTrayIcon::activated, this, [this](QSystemTrayIcon::ActivationReason reason) {
            if (reason == QSystemTrayIcon::Trigger) {
                isVisible() ? hide() : showNormal();
            }
        });
    }

protected:
    // 拦截关闭事件
    void closeEvent(QCloseEvent *event) override {
        if (m_trayIcon->isVisible()) {
            hide();
            event->ignore();
        }
    }

private:
    QSystemTrayIcon *m_trayIcon;
    QMenu *m_trayMenu;
};
#endif // MAINWINDOW_H

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 10:24:04