【发布时间】:2011-12-04 16:15:30
【问题描述】:
我正在开发用户主要使用键盘进行导航的 XBAP 应用程序。当我显示MessageBox 时,我可以按 Enter 将其关闭,但随后主应用程序似乎没有重新获得焦点。我必须在屏幕上手动单击鼠标才能将焦点重新放在应用程序上。
有没有办法解决这个问题?
编辑
我可以验证该应用仍然具有逻辑焦点,但它只是没有键盘焦点
【问题讨论】:
我正在开发用户主要使用键盘进行导航的 XBAP 应用程序。当我显示MessageBox 时,我可以按 Enter 将其关闭,但随后主应用程序似乎没有重新获得焦点。我必须在屏幕上手动单击鼠标才能将焦点重新放在应用程序上。
有没有办法解决这个问题?
编辑
我可以验证该应用仍然具有逻辑焦点,但它只是没有键盘焦点
【问题讨论】:
我发现了一个可行的 hack,虽然我不喜欢它,因为我觉得它将我的 View 与我的 ViewModel 联系起来
我正在使用IsFocused AttachedProperty 将控件绑定到视图后面的布尔属性。同一个 View 还订阅了 DisplayError 事件,该事件显示 MessageBox 错误并随后重置 IsFocused 属性以更新 UI。最后所做的更改是更新我的 ViewModel 以将错误发布到 EventAggregator,而不是使用 MessageBox 处理自己,这可能更好。
我想它可以工作,即使我不喜欢它
【讨论】:
不确定这是否会对您的情况有所帮助,但在我的情况下,我可以将焦点设置回主窗口,这可以通过
App.Current.MainWindow.Focus();
请确保主窗口已正确初始化,如果初始屏幕或某些登录窗口或某些东西最初获取了主窗口角色(即通过 StartupUri),然后没有其他任何更新,则可能不是这种情况。
这对我有用,因为我在主窗口级别处理所有键盘事件以驱动我的视图模型的更新。
【讨论】:
using System.Runtime.InteropServices;
using System.Windows.Interop;
public class Interop
{
[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
public static IntPtr GetWindowHandle(Window window)
{
return new WindowInteropHelper(window).Handle;
}
}
// In main window, when the MessageBox is closed
IntPtr window = Interop.GetWindowHandle(this);
IntPtr focused = Interop.GetForegroundWindow();
if (window != focused)
{
Interop.SetForegroundWindow(window);
}
http://tech.avivo.si/2009/11/how-to-focus-window-in-wpf-when-it-gets-out-of-focus/
【讨论】:
Page 对象,而不是 Window 对象