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

C# 如何启动WinForm应用程序最小化到托盘?,c#,.net,winforms,visual-studio-2008,systray,C#,.net,Winforms,Visual Studio 2008,Systray,我已经成功地创建了一个应用程序,该应用程序使用Notify图标最小化到任务栏。手动关闭表单时,它将从桌面、任务栏和alt选项卡中成功隐藏。当尝试以最小化的应用程序启动时,会出现问题。起初,问题是该应用程序将被最小化,但仍会出现在alt tab对话框中。将FormBorderStyle更改为ToolWindow选项之一(从“无”选项)修复了此问题,但引入了另一个问题。当应用程序首次启动时,最小化窗口的标题栏在“开始”菜单的正上方可见: 打开和关闭表单会使其正确隐藏。我尝试过很多变化,但这里基本上

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

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

Windows状态在设计器中设置为最小化。在构造函数中进行一些初始化后,我有以下几行:

this.Visible = false;
this.ShowInTaskbar = false;
双击Notify图标时,我会看到以下内容:

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

正如我所说,我已经尝试了很多关于这个的小变化(this.Hide(),等等)。有没有办法让NotifyIcon成为主要组件,这样我就可以在保持NotifyIcon运行的同时完全启动和处理表单?必须有一种方法来启动应用程序,使表单最小化,而不会有任何奇怪之处。请帮我找到它

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

this.Visible = false;
this.ShowInTaskbar = false;
并在
InitializeComponent()之后添加

在设计器中,将
ShowInTaskbar
设置为
false
FormWindowState
设置为
Normal

编辑:
如果您在加载事件中发布相同的内容,则窗口确实会最小化,但桌面上仍显示最小化。我认为这是一个bug。

正确的方法是首先防止表单可见。这需要重写SetVisibleCore()。让我们假设NotifyIcon的上下文菜单带有Show和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();
    }
}

注意加载事件中的褶皱,在首次显示主窗体之前不会激发。因此,请确保在窗体的构造函数中进行初始化,而不是在加载事件处理程序中进行初始化。

最小化应用程序时,如果要对Alt+Tab隐藏它,请执行以下操作:

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

关于最小化事件:

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;
关于规范化事件:

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;

我正在阅读所有的答案,看到黑客和黑魔法。。。(恕我冒犯,伙计们)

伙计们,不需要黑客。您甚至不需要设置“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向您的窗口发送一些消息。。。你的钩子/热键等将停止工作。

这个“快速而肮脏的解决方案”对我有效:

$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()

希望它能帮助其他人…

将以下代码从
表单的构造函数移动到
表单的Main\u Load()
。当窗体调整大小()时,在通知图标上使用相同的设置。


或者在窗体的load事件中,因为构造函数是由设计器生成的,并且您很可能会时不时地让更改消失。我同意,load事件将是一个更好的位置,请参见我的编辑。只有当您发布我在
InitializeComponent()之前发布的行时,您的更改才会消失。所有设计器设置都加载到
InitializeComponent()中。好的,我将初始化代码移到加载事件中,并进行了建议的更改。没有骰子。我仍然可以在桌面上看到最小化的标题栏,只是现在即使手动关闭表单,它也不会消失。还有其他想法吗?Re:EDIT:这看起来确实像个bug,但肯定有人在做我想做的事情。我想像这样的虫子会得到更多的关注…太棒了,谢谢!花了一点小的调整,使它与我的特定应用程序,但它的作品伟大!退出单击处理程序中的小更改,当窗体未显示时从上下文菜单退出应用程序时不显示窗体,如果(!mLoadFired)show(),则替换行
带有代码:
if(mLoadFired)Close();else应用程序。Exit()
如果(!this.IsHandleCreated)CreateHandle(),则行
非常有价值。。。它可以防止以后出现线程异常。谢谢你的回答!我正在研究如何为我的程序做到这一点,这个答案是实现我的目标最简单有效的方法。@Brad不,你仍然需要手动添加NotifyIcon。但在你添加了图标后,它就会起作用。我已经准备好了所有的东西来最小化到托盘(通知区域),当手动触发时,它就起作用了。这是唯一一个在启动时自动启动的东西。没有黑客参与。回答得好!工作完美-令人惊讶的是,我花了大约2个小时的谷歌搜索和测试其他方法得到这个。非常感谢。仅供参考-对于VS的新用户-在UI设计器的表单属性中,查找“已显示”事件-而不是“已显示表单”。这是什么语言?