Описание проблемы
Если я создаю немодальное окно в качестве дочернего окна, установив Владелец окна в родительское окно, а затем покажу MessageBox из этого дочернего окна, родительское окно потеряет фокус, если я закрою дочернее окно, Если Windows Explorer или другое приложение открыто, это приложение получит фокус, и основное окно будет скрыто.
Это, похоже, известная проблема, поскольку я видел ее в другой группах новостей, но я не видел хорошего решения. Установка владельца в null в OnDeactivate не является опцией. Установка владельца, прежде чем показывать MessageBox в null и сбросить его после этого, не поможет. Установка владельца в null в событии OnClosed также не помогает.
найдено простое решение
Если у вас возникла такая же проблема, как я описал, поставьте следующий код в OnClosing всех дочерних окон.
void OnClosing(System.ComponentModel.CancelEventArgs e)
base.OnClosing(e);
if (null != Owner) {
Owner.Activate();
}
// ....
За ним может следовать любая дальнейшая логика обработки, допускается даже открытие MessageBoxes.
Пример-код
Вопрос, кажется, намного больше, как я думал. Следующий пример удалит фокус родительского окна, если окно сообщения будет открыто и дочернее окно будет закрыто (скопируйте код в загруженный обработчик событий окна).
Window firstChildWindow = new Window() {
Title = "Floating Window", Width = 100, Height = 70
};
firstChildWindow.Owner = Window.GetWindow(this);
Button button = new Button() { Content="MessageBox"};
button.Click += delegate {
MessageBox.Show("Klicking her breaks the focus-chain."); };
firstChildWindow.Content = button;
firstChildWindow.Show();
Также этот пример разбивает цепочку фокуса:
Window firstChildWindow = new Window() {
Title = "Floating Window", Width = 100, Height = 70
};
firstChildWindow.Owner = Window.GetWindow(this);
firstChildWindow.Show();
Window secondChildWindow = new Window() {
Title="Second Window",Width=100,Height=70};
secondChildWindow.Content = new TextBlock() {
Text="SecondWindow"};
secondChildWindow.Owner = firstChildWindow;
secondChildWindow.Show();
У кого-то есть разрешение на эту проблему. Я думаю о взломе, чтобы вызвать фокус на родителя после закрытия, с Dispatcher или DispachterTimer, или, возможно, это будет работать с ручной фокусировкой на родителя на закрытом, но все это кажется мне очень нечистым (и также немного сложно, если есть более активные окна одного и того же родителя, как в моем текущем приложении).
Никто не знает, насколько это возможно?
Ресурсы
Описание MSDN (см. примечания для не модальных окон, открытых вызовом Show())
Такая же проблема на форумах msdn без соответствующего решения
См. также: Нестабильный фокус приложений WPF