Проблема с закрытием окна

277
07 марта 2018, 05:10

В приложении есть 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

Answer 1

Проблема в том, что у вас окно дважды закрывается и второй раз кидается исключение. Надо так:

    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();
            }
        }
    }
Answer 2

Слишком у вас заморочено как-то.

Я использую 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 как раз установлено по умолчанию.

Answer 3

сделал так:

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();
            }
        }
}
READ ALSO
Не работает ToolTip для неактивных Controls

Не работает ToolTip для неактивных Controls

ЗдравствуйтеНе работает ToolTip для неактивных Controls в моём приложении

228
Разбор dll и добавление их в программу

Разбор dll и добавление их в программу

Есть программа, которая должна выполнять очень сложную функцию (прошу помочь в её реализации):

275
Изменить принцип шифрования

Изменить принцип шифрования

ЗдравствуйтеПишу программу по стеганографии wav файлов

269
Interop.PowerPoint: как задать левый отступ в маркированном списке?

Interop.PowerPoint: как задать левый отступ в маркированном списке?

Есть VSTO Add-in проект для PowerPoint, который в одной из своих частей делает отрисовку маркированного списка

236