Ошибка StackOverflowException при возврате фокуса

Мне надо чтоб при потере фокуса проверялось условие, если true то элемент должен получить фокус, как исправить ошибку?

NameColumn.LostFocus += (object sender, RoutedEventArgs e) =>
{
    if (NameColumn.GetValue(HintAssist.HelperTextProperty) != "")
    {
         NameColumn.Focus(); //StackOverflowException
    }
};

Ответы (1 шт):

Автор решения: VladD

Попробуйте так:

NameColumn.LostFocus += async (object sender, RoutedEventArgs e) =>
{
    if (NameColumn.GetValue(HintAssist.HelperTextProperty) != "")
    {
         await Task.Yield();
         NameColumn.Focus();
    }
};

Более изящный вариант такой:

NameColumn.PreviewLostKeyboardFocus += (o, e) =>
{
    if (NameColumn.GetValue(HintAssist.HelperTextProperty) != "")
        e.Handled = true;
};

Проблема в вашем коде состоит вот в чём. После отправки события LostFocus код WPF синхронно устанавливает фокус на целевой элемент. Посмотреть можно тут: изменение фокуса вызывает изменение IsFocused, которое отправляет LostFocus (в рамках которого вы возвращаете фокус назад), а после установки фокуса таки на целевой элемент ваш TextBox снова теряет фокус, что приводит к рекурсивному запуску той же цепочки и переполнению стека.

Решение — либо возвращать фокус позже, когда смена фокуса полностью состоялась, или (более изящно) отменить смену фокуса на Preview-событии.

→ Ссылка