В приложении есть notifyIcon с contextmenu на нем, в нем пункты Свернуть и Выход.
На закрытие окна есть функция сворачивания в трей если в настройках выбрано "Сворачивать при закрытии". Проблема в том, что при выборе Выход ( -> closeApp() ) в контекстном меню срабатывает Window_Closing и не дает закрыть окно:
private void hideform(object sender, EventArgs e)
{
this.Visibility = Visibility.Hidden;
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (Properties.Settings.Default.minonclose == "True")
{
e.Cancel = true;
this.Visibility = Visibility.Hidden;
}
else
{
this.Close();
notifyicon.Icon = null;
notifyicon.Dispose();
}
}
private void closeApp(object sender, EventArgs e)
{
this.Close();
}
Пробовал вариант с установкой глобального флага bool forceClose:
private void closeApp(object sender, EventArgs e)
{
forceClose = true;
this.Close();
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (forceClose == true)
{
this.Close();
notifyicon.Icon = null;
notifyicon.Dispose();
}
else
{
if (Properties.Settings.Default.minonclose == "True")
{
e.Cancel = true;
this.Visibility = Visibility.Hidden;
}
else
{
this.Close();
notifyicon.Icon = null;
notifyicon.Dispose();
}
}
}
Но приложение завершается с ошибкой:
Необрабатываемое исключение в компоненте приложения. Во время закрытия
окна нельзя установить для Visibility значение Visible или
вызвать Show, ShowDialog, Close или
WindowInteropHelper.EnsureHandle
Проблема в том, что у вас окно дважды закрывается и второй раз кидается исключение. Надо так:
private void closeApp(object sender, EventArgs e)
{
// все закрываем
forceClose = true;
this.Close();
notifyicon.Icon = null;
notifyicon.Dispose();
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (forceClose != true)
{
// тут еще надо проверить, когда вообще этот кусок кода вызывается
{
if (Properties.Settings.Default.minonclose == "True")
{
e.Cancel = true;
this.Visibility = Visibility.Hidden;
}
else {
this.Close();
notifyicon.Icon = null;
notifyicon.Dispose();
}
}
}
Слишком у вас заморочено как-то.
Я использую Hardcodet.NotifyIcon.Wpf (как здесь)
В разметке окна добавлено пространство имен xmlns:tb="http://www.hardcodet.net/taskbar" и в корневой Grid добавлено:
<tb:TaskbarIcon Visibility="Visible" TrayLeftMouseUp="TaskbarIcon_TrayLeftMouseUp">
<tb:TaskbarIcon.ContextMenu>
<ContextMenu>
<MenuItem Header="Свернуть" Click="MenuItem1_Click"/>
<MenuItem Header="Закрыть" Click="MenuItem2_Click"/>
</ContextMenu>
</tb:TaskbarIcon.ContextMenu>
</tb:TaskbarIcon>
Код окна:
public bool HideOnClose { get; set; }
bool forceClose = false;
public MainWindow()
{
InitializeComponent();
}
private void MenuItem1_Click(object sender, RoutedEventArgs e)
{
Hide();
}
private void MenuItem2_Click(object sender, RoutedEventArgs e)
{
forceClose = true;
Close();
}
private void Window_Closing(object sender, CancelEventArgs e)
{
if (!forceClose && HideOnClose)
{
e.Cancel = true;
Hide();
}
}
private void TaskbarIcon_TrayLeftMouseUp(object sender, RoutedEventArgs e)
{
Show();
}
В обработчике Window_Closing дополнительно вызывать Close() не нужно, достаточно установить e.Cancel в true если закрывать не нужно и в false если нужно, false как раз установлено по умолчанию.
сделал так:
private void closeApp(object sender, EventArgs
{
forceClose = true;
this.Close();
notifyicon.Icon = null;
notifyicon.Dispose();
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (forceClose == false)
{
if (Properties.Settings.Default.minonclose == "True")
{
e.Cancel = true;
this.Visibility = Visibility.Hidden;
}
else
{
e.Cancel = false;
notifyicon.Icon = null;
notifyicon.Dispose();
}
}
}
Сборка персонального компьютера от Artline: умный выбор для современных пользователей