如何在对话框后设置焦点控件?

时间:2022-08-26 21:44:17

I'm working on an XBAP app where Users primarily use the Keyboard for Navigation. When I display a MessageBox, I can hit Enter to close it but then the main application doesn't seem to regain focus. I have to manually click the mouse on the screen to put focus back on the application.

我正在开发一个XBAP应用程序,用户主要使用键盘进行导航。当我显示一个MessageBox时,我可以点击Enter关闭它,但是主应用程序似乎没有重新获得焦点。我必须手动点击屏幕上的鼠标,将焦点放在应用程序上。

Is there a way around this?

有办法解决这个问题吗?

Edit

编辑

I can verify that the app still has Logical Focus, but it just doesn't have Keyboard Focus

我可以验证这个应用程序仍然有逻辑焦点,但它只是没有键盘焦点

3 个解决方案

#1


0  

I found a hack that works, although I don't like it because I feel it ties my Views to my ViewModel

我发现了一个有效的方法,尽管我不喜欢它,因为我觉得它把我的观点和我的视图模型联系在一起

I'm using an IsFocused AttachedProperty to bind a control to a boolean property behind the View. The same View is also subscribing to a DisplayError event that displays a MessageBox error and reset the IsFocused property afterwards so it updates the UI. Last change made was to update my ViewModels to publish errors to the EventAggregator instead of handling themselves with a MessageBox, which is probably better anyways.

我使用isfocus AttachedProperty将控件绑定到视图后面的boolean属性。同样的视图也订阅DisplayError事件,该事件显示一个MessageBox错误,然后重置IsFocused属性,以便它更新UI。最后做的更改是更新我的viewmodel,将错误发布到EventAggregator,而不是使用MessageBox处理它们自己,无论如何,这可能更好。

I suppose it works, even if I don't like it

我想这行得通,即使我不喜欢

#2


0  

Not sure if this will help your situation but in my circumstance it was ok for me to set focus back to main window, which was able to be accomplished with

我不确定这是否会对你的情况有所帮助,但在我的情况下,我可以把焦点放在主窗口上,这是可以完成的

App.Current.MainWindow.Focus();

Just be sure main window is properly initialized, which may not be the case if a splash screen or some login window or something initially grabbed the main window role (ie by StartupUri) and then nothing else was updated thereafter.

只要确保主窗口被正确初始化就可以了,如果一个启动屏幕或某个登录窗口或其他什么东西最初占据了主窗口角色(即StartupUri),那么以后就不会更新其他内容了。

This worked for me since I was handling all keyboard events at the main window level to drive updates to my view model.

这对我很有用,因为我在主窗口级别处理所有键盘事件,以驱动视图模型的更新。

#3


-1  

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/

http://tech.avivo.si/2009/11/how-to-focus-window-in-wpf-when-it-gets-out-of-focus/

#1


0  

I found a hack that works, although I don't like it because I feel it ties my Views to my ViewModel

我发现了一个有效的方法,尽管我不喜欢它,因为我觉得它把我的观点和我的视图模型联系在一起

I'm using an IsFocused AttachedProperty to bind a control to a boolean property behind the View. The same View is also subscribing to a DisplayError event that displays a MessageBox error and reset the IsFocused property afterwards so it updates the UI. Last change made was to update my ViewModels to publish errors to the EventAggregator instead of handling themselves with a MessageBox, which is probably better anyways.

我使用isfocus AttachedProperty将控件绑定到视图后面的boolean属性。同样的视图也订阅DisplayError事件,该事件显示一个MessageBox错误,然后重置IsFocused属性,以便它更新UI。最后做的更改是更新我的viewmodel,将错误发布到EventAggregator,而不是使用MessageBox处理它们自己,无论如何,这可能更好。

I suppose it works, even if I don't like it

我想这行得通,即使我不喜欢

#2


0  

Not sure if this will help your situation but in my circumstance it was ok for me to set focus back to main window, which was able to be accomplished with

我不确定这是否会对你的情况有所帮助,但在我的情况下,我可以把焦点放在主窗口上,这是可以完成的

App.Current.MainWindow.Focus();

Just be sure main window is properly initialized, which may not be the case if a splash screen or some login window or something initially grabbed the main window role (ie by StartupUri) and then nothing else was updated thereafter.

只要确保主窗口被正确初始化就可以了,如果一个启动屏幕或某个登录窗口或其他什么东西最初占据了主窗口角色(即StartupUri),那么以后就不会更新其他内容了。

This worked for me since I was handling all keyboard events at the main window level to drive updates to my view model.

这对我很有用,因为我在主窗口级别处理所有键盘事件,以驱动视图模型的更新。

#3


-1  

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/

http://tech.avivo.si/2009/11/how-to-focus-window-in-wpf-when-it-gets-out-of-focus/