如何启动WinForm应用程序最小化到托盘?

时间:2009-11-13 17:25:56

标签: c# .net winforms visual-studio-2008 systray

我已经成功创建了一个使用NotifyIcon最小化托盘的应用程序。手动关闭表单后,它将成功从桌面,任务栏和alt-tab中隐藏。尝试最小化应用程序时,会出现此问题。起初问题是应用程序将被最小化但仍会出现在alt-tab对话框中。将FormBorderStyle更改为ToolWindow选项之一(来自“None”选项)修复此问题,但引入了另一个问题。当应用程序首次启动时,在开始菜单上方可以看到最小化窗口的标题栏:

enter image description here

打开表单并关闭它会使其正确隐藏。我已经尝试了很多变化,但这里基本上是它现在如何工作......

WindowState在Designer中设置为Minimized。在构造函数中进行一些初始化之后,我有以下几行:

this.Visible = false;
this.ShowInTaskbar = false;

双击NotifyIcon时,我有以下内容:

 this.WindowState = FormWindowState.Normal;
 this.Visible = true;
 this.ShowInTaskbar = true;

就像我说的那样,我尝试了很多微小的变化(this.Hide()等)。有没有办法让NotifyIcon成为主要组件,这样我可以完全启动并处理表单,同时让NotifyIcon运行?必须有一种方法来启动应用程序与最小化的形式没有任何奇怪。请帮帮我找到它!

6 个答案:

答案 0 :(得分:76)

执行此操作的正确方法是防止表单首先显示。这需要重写SetVisibleCore()。让我们假设NotifyIcon的上下文菜单带有Show and Exit命令。您可以像这样实现它:

public partial class Form1 : Form {
    public Form1() {
        InitializeComponent();
        notifyIcon1.ContextMenuStrip = contextMenuStrip1;
        this.showToolStripMenuItem.Click += showToolStripMenuItem_Click;
        this.exitToolStripMenuItem.Click += exitToolStripMenuItem_Click;
    }

    private bool allowVisible;     // ContextMenu's Show command used
    private bool allowClose;       // ContextMenu's Exit command used

    protected override void SetVisibleCore(bool value) {
        if (!allowVisible) {
            value = false;
            if (!this.IsHandleCreated) CreateHandle();
        }
        base.SetVisibleCore(value);
    }

    protected override void OnFormClosing(FormClosingEventArgs e) {
        if (!allowClose) {
            this.Hide();
            e.Cancel = true;
        }
        base.OnFormClosing(e);
    }

    private void showToolStripMenuItem_Click(object sender, EventArgs e) {
        allowVisible = true;
        Show();
    }

    private void exitToolStripMenuItem_Click(object sender, EventArgs e) {
        allowClose = true;
        Application.Exit();
    }
}

注意Load事件的皱纹,在首次显示主窗体之前不会触发。所以一定要在表单的构造函数中进行初始化,而不是Load事件处理程序。

答案 1 :(得分:17)

构造函数中,删除以下两行:

this.Visible = false;
this.ShowInTaskbar = false;

并在InitializeComponent();之后添加:

this.WindowState = FormWindowState.Minimized;

在设计师中,将ShowInTaskbar设为false& FormWindowStateNormal

修改 如果您在Load事件中发布相同内容,则窗口会尽量减少,但仍会在桌面上显示最小化。我认为这是一个错误。

答案 2 :(得分:16)

我正在阅读所有的答案,看到黑客和黑魔法......(没有冒犯,伙伴)

伙计们,不需要黑客。你甚至不需要设置“ShowInTaskbar = false”和其他东西。就这样做:

    //"Form Shown" event handler
    private void Form_Shown(object sender, EventArgs e)
    {
        //to minimize window
        this.WindowState = FormWindowState.Minimized;

        //to hide from taskbar
        this.Hide();
    }

注意:我强烈建议不要触摸“ShowInTaskbar”属性。例如,如果您的应用程序注册系统范围的热键或其他类似的东西(钩子等) - 设置ShowInTaskBar = false并最小化您的应用程序将阻止Windows向您的窗口发送一些消息...并且您的钩子/热键/等将停止工作。

答案 3 :(得分:2)

最小化应用程序并希望将其从Alt + Tab隐藏时:

当您将边框样式设置为工具窗口时,还需要设置不透明度以停止显示在“开始”菜单附近的标题栏。

On Minimize Event:

this.Visible = false;
this.Opacity = 0;
this.FormBorderStyle = FormBorderStyle.FixedToolWindow;
this.ShowInTaskbar = false;

关于规范化事件:

this.Visible = true;
this.Opacity = 100;
this.FormBorderStyle = FormBorderStyle.FixedSingle; //or whatever it was previously set to
this.ShowInTaskbar = true;

答案 4 :(得分:0)

这个"快速而肮脏的修复"为我工作:

$form1.FormBorderStyle = "fixedtoolwindow"
$form1.top = -1000000
$form1.Left = -1000000
$form1.Width = 10
$form1.Height = 10
$form1.WindowState = "normal"
$form1.ShowInTaskbar = $False
$form1.Opacity = 0
$form1.Hide()

希望它可以帮助别人...

答案 5 :(得分:0)

将以下代码从Form的构造函数移动到Form_Main_Load()。在Notification_Icon when Form_Resize()上进行了相同的设置。

// Hide the Form to System Tray
this.WindowState = FormWindowState.Minimized;