Обработка событий потери фокуса и деактивации

#.net #wpf

#.net #wpf

Вопрос:

У меня есть этот код, прикрепленный к событиям LostFocus и Deactivate :

     private void Window_LostFocus(object sender, EventArgs e)
    {
        try
        {
            this.Close();
        }
        catch (InvalidOperationException ex) { }
    }
  

Странный пробел catch вызван тем фактом, что если я закрываю (нажатием X ) окно, оно также появляется Deactivate , даже если в этом случае я пытаюсь закрыть уже закрывающееся окно. Есть ли лучший способ справиться с этим?

Чтобы быть более понятным, мой сценарий таков: у меня есть окно, которое нужно было закрыть при lostfocus, деактивации и закрытии с помощью обычного X или Alt f4 .

Ответ №1:

Другой вариант (помимо наличия IsClosing состояния) — подключиться к событию закрытия и отказаться от подписки на события deactivated и lost focus, чтобы предотвратить их вызов:

 private void Window_Closing(object sender, EventArgs e)
{
    Deactivated -= Window_Deactivated;
    LostFocus -= Window_LostFocus;
}
  

Комментарии:

1. Является ли это на 100% безопасным для условной гонки решением?

2. Обработчики событий вызываются синхронно, и в дополнение к этому этот должен вызываться только в потоке пользовательского интерфейса. Поэтому, если вы не делаете какие-то неприятные вещи из фоновых потоков в своем окне, это должно быть потокобезопасно.

Ответ №2:

Вы могли бы попробовать что-то вроде этого:

 bool IsClosing = false;
private void Window_LostFocus(object sender, RoutedEventArgs e)
{
    CloseWindow();
}

private void Window_Deactivated(object sender, EventArgs e)
{
    CloseWindow();
}

void CloseWindow()
{
    if (IsClosing == false)
    {
        IsClosing = true;
        this.Close();
    }
}
  

Комментарии:

1. Да, я тоже думал об этом, но это тоже грязный взлом.