50

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

在此处输入图像描述

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

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

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

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

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

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

4

6 回答 6

83

这样做的正确方法是首先防止表单变得可见。这需要重写 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 事件处理程序中。

于 2009-11-13T22:26:48.203 回答
23

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

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

于 2011-12-13T08:52:31.053 回答
21

构造函数中,删除这两行:

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

并在之后添加InitializeComponent();

this.WindowState = FormWindowState.Minimized;

在设计器中,设置ShowInTaskbarfalse& 。FormWindowStateNormal

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

于 2009-11-13T17:36:59.423 回答
2

当最小化应用程序并且您想从 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;
于 2011-01-26T11:51:13.257 回答
0

将以下代码从Form的构造函数移动到Form_Main_Load(). 使用相同的设置Notification_Icon when Form_Resize()

// Hide the Form to System Tray
this.WindowState = FormWindowState.Minimized;
于 2019-10-07T14:16:41.237 回答
-1

这个“快速而肮脏的修复”对我有用:

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

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

于 2016-08-31T13:46:36.513 回答