Ответ 1
Вы можете установить
notifyIcon1.Visible = false;
ИЛИ
notifyIcon.Icon = null;
в событии закрытия формы.
Есть много вопросов о SO, которые задают одно и то же сомнение. Решением для этого является установка
notifyIcon.icon = null
и вызов Dispose
для него в событии FormClosing.
В моем приложении такой формы нет, но есть значок уведомления, который обновляется в Events.
При создании я скрою свою форму и создаю ShowInTaskbar
свойство false
. Следовательно, я не могу иметь события FormClosing или FormClosed.
Если это приложение получает событие для выхода, оно вызывает Process.GetCurrentProcess().Kill();
для выхода.
Я добавил notifyIcon.icon = null
, а также Dispose перед убийством, но значок остается на панели задач до тех пор, пока я наведите указатель мыши на него.
EDIT. Если я предполагаю, что это поведение вызвано вызовом GetCurrentProcess().Kill()
, есть ли элегантный способ выйти из приложения, которое очистит все ресурсы и удалит значок из панели задач.
Вы можете установить
notifyIcon1.Visible = false;
ИЛИ
notifyIcon.Icon = null;
в событии закрытия формы.
Единственное решение, которое сработало для меня, заключалось в том, чтобы использовать закрытое событие и скрывать и удалять значок.
icon.BalloonTipClosed += (sender, e) => {
var thisIcon = (NotifyIcon)sender;
thisIcon.Visible = false;
thisIcon.Dispose();
};
Используйте notifyIcon.Visible = False
в событии FormClosing
Используйте этот код, когда вы хотите сделать это, когда вы нажимаете кнопку Выйти или Закрыть:
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;
Компоненты должны быть расположены в правильном порядке:
NotifyIcon.Icon.Dispose();
NotifyIcon.Dispose();
Добавьте это в событие закрытия MainWindow
.
Надеюсь, это поможет.
Это нормальное поведение, к сожалению; это связано с тем, как работает Windows. Вы не можете ничего с этим поделать.
См. Проблема с NotifyIcon, которая не исчезает в приложении Winforms для некоторых предложений, но никто из них никогда не работал у меня.
Также см. Значок уведомления остается в системном лотке при закрытии приложения
Microsoft отметила это как "не исправит" Microsoft Connect.
Я не думаю, что у 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();
}
Я могу сказать, что вы можете решить проблему, просто используя метод .dispose(), но это не вызывается, если вы убиваете процесс вместо выхода из приложения.
обратитесь к Application.Exit, если вы создали простую прикладную программу Windows Form, которая ссылается на Environment.Exit, который является более общим.
Попробуйте Application.DoEvents();
после установки notifyIcon.Icon
на null
и утилизации:
notifyIcon.Icon = null;
notifyIcon.Dispose();
Application.DoEvents();
И рассмотрим Environment.Exit(0);
вместо Process.GetCurrentProcess().Kill()
.
Я попробовал все это, и ни один из них не работал для меня. Подумав об этом некоторое время, я понял, что приложение, создающее "воздушный шар", закрывается, прежде чем оно успевает фактически избавиться от воздушного шара. Я добавил цикл while непосредственно перед Application.Exit()
содержащий команду Application.DoEvents()
. Это позволило моему 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();
}
У меня была такая же проблема, как и вы.
Правильный способ отправки сообщения WM_CLOSE в процесс.
Я использую код С#, который я нашел в этой статье.
http://social.msdn.microsoft.com/Forums/vstudio/en-US/82992842-80eb-43c8-a9e6-0a6a1d19b00f/terminating-a-process-in-a-friendly-way
Правильный ответ уже дан. Но вы также должны обеспечить задержку, например, с помощью таймера. Только тогда приложение может удалить значок в фоновом режиме.
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
}
редактировать коды... Designer.cs, как показано ниже.
protected override void Dispose(bool disposing)
{
if (disposing )
{
this.notifyicon.Dispose();
}
base.Dispose(disposing);
}