将应用程序最小化到系统托盘

123

我有一个由C#和Visual Studio 2010驱动的Windows表单应用程序。

如何将我的应用程序最小化到系统托盘(而不是任务栏),然后在系统托盘中双击时将其恢复?有什么想法吗?还有,如何在系统托盘图标中添加一些菜单,右键单击它时显示一个菜单,像登录、断开连接、连接等等。此外,是否有任何方法可以显示从系统托盘弹出的气球状提示框?

附:我已经添加了一个notifyIcon,但我不知道如何使用它。


在这里,您可以下载一个很棒的示例代码 https://www.simple-talk.com/dotnet/.net-framework/creating-tray-applications-in-.net-a-practical-guide/。 - NoWar
你需要确保进入表单的Designer.cs并“注册”事件处理程序,否则这些都不会起作用(我无法弄清楚)。您可以通过添加类似以下内容来实现:this.Resize += new System.EventHandler(this.ManagementForm_Resize); - Brad
9个回答

160

在窗体的Resize事件中处理。在此处理程序中,您需要重写Resize事件的基本功能,使窗体最小化到系统托盘而不是任务栏。可通过以下方式在窗体的Resize事件处理程序中完成:检查窗体的WindowState属性是否设置为FormWindowState.Minimized。如果是,则隐藏窗体,启用NotifyIcon对象并显示一些信息的气球提示。一旦WindowState变为FormWindowState.Normal,通过将其Visible属性设置为false来禁用NotifyIcon对象。现在,您希望在任务栏上双击NotifyIcon对象时重新显示窗口。为此,请处理NotifyIcon的MouseDoubleClick事件。在这里,使用Show()方法显示窗体。

private void frmMain_Resize(object sender, EventArgs e)
{
    if (FormWindowState.Minimized == this.WindowState)
    {
       mynotifyicon.Visible = true;
       mynotifyicon.ShowBalloonTip(500);
       this.Hide();
    }

    else if (FormWindowState.Normal == this.WindowState)
    {
       mynotifyicon.Visible = false;
    }
}

5
你可以更改 Form 的 FormBorderStyle 属性。http://msdn.microsoft.com/zh-cn/library/system.windows.forms.form.formborderstyle.aspx - CD..
谢谢!它起作用了。还有,您有什么想法可以禁用右上角的最小化、关闭、最大化按钮吗?谢谢。 - vvavepacket
8
如何禁用WinForm上的最小化和最大化按钮?您可以使用以下代码禁用WinForm窗口上的最小化和最大化按钮:private const int MF_BYCOMMAND = 0x00000000; public const int SC_CLOSE = 0xF060; public const int SC_MAXIMIZE = 0xF030; public const int SC_MINIMIZE = 0xF020; [DllImport("user32.dll")] public static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert); [DllImport("user32.dll")] public static extern int DeleteMenu(IntPtr hMenu, int nPosition, int wFlags); protected override void OnLoad(EventArgs e) { base.OnLoad(e); IntPtr hMenu = GetSystemMenu(this.Handle, false); if (hMenu != IntPtr.Zero) { DeleteMenu(hMenu, SC_CLOSE, MF_BYCOMMAND); DeleteMenu(hMenu, SC_MINIMIZE, MF_BYCOMMAND); DeleteMenu(hMenu, SC_MAXIMIZE, MF_BYCOMMAND); } }这将从系统菜单中删除最小化和最大化按钮。 - CD..
7
如何在 .NET 中使窗口始终保持在最上层? - CD..
另外,只是想指出似乎Resize是那种可能会吞噬异常的地方。 - Jonathon Reinhart
显示剩余2条评论

76

我发现这个可以完成整个解决方案。上面的答案无法将窗口从任务栏中删除。

private void ImportStatusForm_Resize(object sender, EventArgs e)
{
    if (this.WindowState == FormWindowState.Minimized)
    {
        notifyIcon.Visible = true;
        notifyIcon.ShowBalloonTip(3000);
        this.ShowInTaskbar = false;
    }
}

private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
{
    this.WindowState = FormWindowState.Normal;
    this.ShowInTaskbar = true;
    notifyIcon.Visible = false;
}

此外,使用表单设计器设置通知图标控件的以下属性也是很好的选择。
this.notifyIcon.BalloonTipIcon = System.Windows.Forms.ToolTipIcon.Info; //Shows the info icon so the user doesn't think there is an error.
this.notifyIcon.BalloonTipText = "[Balloon Text when Minimized]";
this.notifyIcon.BalloonTipTitle = "[Balloon Title when Minimized]";
this.notifyIcon.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon.Icon"))); //The tray icon to use
this.notifyIcon.Text = "[Message shown when hovering over tray icon]";

9
this.WindowState = FormWindowState.Normal; 之前加上 this.Show(); - developerwjk
1
"the user doesn't thing" 中有错别字。 ;) - Andrew
1
@developerwjk,这不是因为他没有调用Hide()而导致的缺失。但是这种方法的问题在于,当您按下Alt-Tab时,窗口仍然会出现。我更喜欢调用Hide(),这样您根本不需要使用ShowInTaskbar属性。 - Andrew
@Andrew,我在使用Show()Hide()时遇到了问题;在隐藏、显示、再次隐藏后,它将无法再次显示。 - newbieguy
@newbieguy,我猜你需要创建一个新问题,因为你的问题不适合在评论中回答。你需要提供更多信息,例如你正在使用的代码。你可以包含一个链接到你尝试使用的答案。 - Andrew

22
不要忘记向您的notifyIcon添加图标文件,否则它将不会出现在托盘中。

以下是有关编程的内容翻译为中文:如何强制使用默认图标?请提供主题中最需要的部分。 - T.Todua

17

我会选择

private void Form1_Resize(object sender, EventArgs e)
{
     if (FormWindowState.Minimized == this.WindowState)
     {
          notifyIcon1.Visible = true;
          notifyIcon1.ShowBalloonTip(500);
          this.Hide();    
     }
     else if (FormWindowState.Normal == this.WindowState)
     {
          notifyIcon1.Visible = false;
     }
}

private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
{
     this.Show();
     this.WindowState = FormWindowState.Normal;
}

13

试一试

 private void Form1_Load(object sender, EventArgs e)
    {
        notifyIcon1.BalloonTipText = "Application Minimized.";
        notifyIcon1.BalloonTipTitle = "test";
    }

    private void Form1_Resize(object sender, EventArgs e)
    {
        if (WindowState == FormWindowState.Minimized)
        {
            ShowInTaskbar = false;
            notifyIcon1.Visible = true;
            notifyIcon1.ShowBalloonTip(1000);
        }
    }

    private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
    {
        ShowInTaskbar = true;
        notifyIcon1.Visible = false;
        WindowState = FormWindowState.Normal;
    }

2
如果你只是从任务栏隐藏窗口而不是调用this.Hide(),那么在执行Alt-Tab时窗口仍然会出现。 - Andrew

3

这是我在应用程序中使用的方法,它相当简单明了,但我很乐意根据您的评论提供更多细节。

    public Form1()
    {
        InitializeComponent();

        // When window state changed, trigger state update.
        this.Resize += SetMinimizeState;

        // When tray icon clicked, trigger window state change.       
        systemTrayIcon.Click += ToggleMinimizeState;
    }      

    // Toggle state between Normal and Minimized.
    private void ToggleMinimizeState(object sender, EventArgs e)
    {    
        bool isMinimized = this.WindowState == FormWindowState.Minimized;
        this.WindowState = (isMinimized) ? FormWindowState.Normal : FormWindowState.Minimized;
    }

    // Show/Hide window and tray icon to match window state.
    private void SetMinimizeState(object sender, EventArgs e)
    {    
        bool isMinimized = this.WindowState == FormWindowState.Minimized;

        this.ShowInTaskbar = !isMinimized;           
        systemTrayIcon.Visible = isMinimized;
        if (isMinimized) systemTrayIcon.ShowBalloonTip(500, "Application", "Application minimized to tray.", ToolTipIcon.Info);
    }

2
这个和其他解决方案都有一个问题:如果窗体被其他窗口隐藏,用户很可能不想在单击图标时将其最小化。相反,它应该是焦点。请参见我的问题:http://stackoverflow.com/questions/36797442/proper-way-of-activating-my-mainform-from-a-notifyicon-if-it-wasnt-focused-alre - maf-soft

1
在系统托盘中点击图像时,您可以验证框架是否可见,然后您必须设置 Visible = true 或 false。

1

对于您的右键通知菜单,请向表单添加上下文菜单并进行编辑,通过双击每个上下文菜单项设置鼠标单击事件,然后通过在notifyicon属性中选择ContextMenuStrip将其附加到notifyicon1。


-3

this.WindowState = FormWindowState.Minimized;

的意思是将窗口状态设置为最小化。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接