即使关闭应用程序,NotifyIcon仍保留在托盘中,但在鼠标悬停时消失


76

因此,有很多问题都提出了同样的疑问。解决方案是设置

notifyIcon.icon = nullDispose在FormClosing事件中调用它。

在我的应用程序中,没有这种形式,但是具有通知图标,该图标会在事件上更新。在创建时,我将隐藏表单并进行ShowInTaskbar属性设置false。因此,我不能有“ FormClosing”或“ FormClosed”事件。

如果此应用程序获得退出事件,它将调用Process.GetCurrentProcess().Kill();退出。

notifyIcon.icon = null在杀死之前,我已经添加了“处置”功能,但图标仍然保留在任务栏上,直到我将鼠标悬停在它上面。

编辑:如果我认为此行为是由于调用引起的GetCurrentProcess().Kill(),是否有任何优雅的方法可以退出应用程序,从而清除所有资源并从系统托盘中删除图标。


1
是时候接受一个答案了,您不觉得:D让我为您推荐“松饼人”之一:D
Felix D.

@Nudity问题是我刚刚摆脱了该通知图标...现在我没有该代码来验证任何解决方案:-)
Swanand

我会做一下:D,而Dispose()修复它:D
Felix D.

Answers:


52

您可以设置

notifyIcon1.Visible = false;

要么

notifyIcon.Icon = null;

在表单关闭事件中。


2
无法解决问题。
Gigi 2014年

@Gigi你尝试了吗?
杰森·迪亚斯

14
icon.BalloonTipClosed += (sender, e) => { var thisIcon = (NotifyIcon)sender; thisIcon.Visible = false; thisIcon.Dispose(); };
松饼人

2
@TheMuffinMan:这太好了!就像解决问题一样解决了我的问题。非常感谢!
C4d

5
对于那些将依靠此答案的用户,请务必注意,此操作确实可以解决问题。如果您的图标仍然存在,那是因为您正在调试(并非所有PC都在进行调试,但是我们这里有11个中有2个在进行调试)。如果您运行exe,该图标实际上将消失。
弗朗克

20

对我而言唯一有效的解决方案是使用Closed事件并隐藏和处置图标。

icon.BalloonTipClosed += (sender, e) => { 
                                            var thisIcon = (NotifyIcon)sender;
                                            thisIcon.Visible = false;
                                            thisIcon.Dispose(); 
                                        };

4
这应该是公认的答案……Dispose()这就是您所需要的!
Felix D.

这个叫什么?+ =(发送者,e)=> {//代码};
松饼男孩

2
@ user3365695这是一个lambda表达式。检查此链接了用3种方式来指定委托的例子msdn.microsoft.com/en-us/library/...
松饼人

我记得我在学习的时候对代表的解释并不好。委托只是提供方法名称的一种方法,稍后将由某些方法调用该方法。您可以使用与事件期望的签名相匹配的任何方法。在这种情况下,一旦Balloon提示内部调用了该BalloonTipClosed事件,我们将注册一个要调用的方法。在此示例中,从语法上讲,我们没有提供方法的名称,而是定义了所谓的匿名函数/方法。这是一个较新的代码功能,这就是为什么您会看到多种实现方法的原因delegate(string s) {//code}
松饼人

无法

14

组件必须按照正确的顺序进行处理,如下所示:

NotifyIcon.Icon.Dispose();

NotifyIcon.Dispose();

将此添加到MainWindow结束事件。

希望这会有所帮助。


11

notifyIcon.Visible = FalseFormClosing事件中使用


2
做一个干净的清理你仍然应该调用notifyIcon.Dispose()。当您的类没有函数时,您可以调用此函数,则应实现IDisposable
丹尼尔·艾森瑞希

不知道为什么这没有被标记为答案,但是它也解决了我的问题...谢谢@Ismael
Kevin Moore

@KevinMoore,因为OP明确表示他没有Form他们可以处理的FormClosing活动
ardila

9

按下退出或关闭按钮时,请使用以下代码:

private void ExitButton_Click(object sender, EventArgs e)
{
    notifyIcon.Dispose();
    Application.Exit(); // or this.Close();
}

如果要在关闭表单时执行此代码,请使用以下代码:

private void Form1_FormClosing(object sender, EventArgs e)
{
    notifyIcon.Dispose();
    Application.Exit(); // or this.Close();
}

重要的代码是这样的:

notifyIcon.Dispose();

我尝试了下面的代码,它起作用了。私人无效Window_Closed(object sender,EventArgs e){mNotifyIcon.Dispose(); }
Garland '18

3

不幸的是,这是正常的行为;这是由于Windows的工作方式。您真的无能为力。

请参阅在Winforms App上不消失的NotifyIcon问题,以获取一些建议,但这些建议都不对我有用。

另请参阅在应用程序关闭时,通知图标停留在系统托盘中

Microsoft在Microsoft Connect上将此标记为“无法解决”。


3
我觉得Windows一直在做这件事。
j_mcnally

在相似的情况下,OSX经常会在任务栏中留下一个GAP,我猜这两个操作系统是如何绘制其任务/菜单栏的是一个怪癖。
j_mcnally

除了“ GetCurrentProcess.Kill()”之外,没有什么优雅的方法可以退出此过程,这会改变我的这种行为吗?
斯旺南德

它可能!我觉得您正在杀死它是导致某些问题的原因。在将图标设置为nil并进行处置之后,您可以尝试在杀死之前等待下一个运行循环。
j_mcnally

1
@MatthewWatson您能给我提供“无法修复”的任何链接吗?
斯旺德

2

我不认为WPF拥有自己的NotifyIcon,对吗?如果您使用的是第三方Harcodet.Wpf.TaskbarNotification,请尝试以下操作:

为了防止在关闭窗口(在后台运行)时关闭我的应用程序,我分离了关闭窗口(点击右上角的x按钮)并实际上将其关闭(通过上下文菜单)的逻辑。为此,请设置上下文菜单_isExplicitClose为true。否则,它将仅隐藏窗口并继续运行。

它的作用是,在明确关闭时,在关闭之前隐藏任务栏图标和表格。这样,在应用程序关闭后,图标不会在周围徘徊。

private bool _isExplicitClose;
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
    base.OnClosing(e);

    if (!_isExplicitClose)
    {
        e.Cancel = true;
        Hide();
    }
}

protected void QuitService(object sender, RoutedEventArgs e)
{
   _isExplicitClose = true;
   TaskbarIcon.Visibility = Visibility.Hidden;
   Close();
}

2

尝试Application.DoEvents();设置完成后notifyIcon.Icon,以null和处置:

notifyIcon.Icon = null;
notifyIcon.Dispose();
Application.DoEvents();

并考虑Environment.Exit(0);代替Process.GetCurrentProcess().Kill()


1

我可以告诉您可以仅使用.dispose()方法解决问题,但是如果您杀死进程而不是退出应用程序,则不会调用该方法。

如果您已经构建了一个简单的Windows Form应用程序,请参考Application.Exit,否则请参考更通用的Environment.Exit


1

我尝试了所有这些,但没有一个对我有用。考虑了一会儿之后,我意识到创建“气球”的应用程序在有机会真正处置气球之前就退出了。我在Application.Exit()包含Application.DoEvents()命令之前添加了一个while循环。这使我NotifyIcon1_BalloonTipClosed可以在退出之前完成该图标的处理。

while (notifyIcon1.Visible)
{
    Application.DoEvents();
}
Application.Exit();

和技巧关闭方法:(您需要包括thisIcon.visible = false以便此工作)

private void NotifyIcon1_BalloonTipClosed(object sender, EventArgs e)
{
    var thisIcon = (NotifyIcon)sender;
    thisIcon.Icon = null;
    thisIcon.Visible = false;
    thisIcon.Dispose();
}


0

按照以下代码编辑... Designer.cs的代码。

        protected override void Dispose(bool disposing)
           {
           if (disposing )
               {
               this.notifyicon.Dispose();
               }
           base.Dispose(disposing);
           }

请添加一些说明。
Mush先生

0

对我有效的唯一方法是:

  1. 在设计屏幕上,更改notifyicon1属性visible = false

  2. 在主窗体“已激活”事件上插入以下代码:

NotifyIcon1.Visible = True
  1. 在主表单“关闭”事件上插入以下代码:
NotifyIcon1.Visible = false
NotifyIcon1.Icon.Dispose()
NotifyIcon1.Dispose()

-1

正确的答案已经给出。但是您还必须提供延迟,例如使用计时器。只有这样,应用程序仍可以删除背景中的图标。

private System.Windows.Forms.Timer mCloseAppTimer;
private void ExitButton_Click(object sender, EventArgs e) 
{ 
    notifyIcon.Visible = false; notifyIcon.Dispose; 
    mCloseAppTimer = new System.Windows.Forms.Timer(); 
    mCloseAppTimer.Interval = 100; 
    mCloseAppTimer.Tick += new EventHandler(OnCloseAppTimerTick); 
} 
private void OnCloseAppTimerTick(object sender, EventArgs e) 
{ 
    Environment.Exit(0); // other exit codes are also possible 
}

1
当然使用计时器是一个过大的选择-Thread.Sleep(1000)不会一样吗?所以也没有“暂停”任何GUI ECT你甚至可以一个新的线程中使用它
马克
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.