SplashScreen.Close() 窃取 MainWindow 的焦点
当 SplashScreen 关闭(手动或通过 AutoClose)时,它会在淡出动画期间窃取 MainWindow 的焦点。这会导致主窗口的标题从活动状态切换到非活动状态(灰色),然后再切换到活动状态。有什么技巧可以防止 SplashScreen 抢走焦点吗?
When the SplashScreen closes (either manually or by AutoClose), it steals the focus of the MainWindow during the fade-out animation. This results in the caption of the main window switching from active to inactive (grey) to active. Is there any trick to keep the SplashScreen from stealing focus?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
告诉 SplashScreen MainWindow 是它的父窗口。当子窗口失去焦点时,其父窗口将获得焦点。如果没有父窗口,则由窗口管理器决定。splashScreen.Show(mainWindow);
编辑:
我刚刚发现有一个 SplashScreen 类。看来您使用的是该类,而不仅仅是我假设的普通表单。
因此,我只是使用 SplashScreen 制作了一个简单的 WPF 应用程序,但对我来说,上述效果并未发生。主窗口没有失去焦点。
我建议您注释掉应用程序初始化代码的部分内容,直到闪烁停止。然后你就有了一个起点来进行更多研究为什么焦点会丢失。
EDIT2:
在不知道你的代码的情况下,我尝试重现这种现象,这并不难。无论我尝试什么,焦点变化总是发生在主窗口已经显示并具有焦点时。
因此,我看到的最佳解决方案是在调用启动屏幕的 Close() 方法之后手动显示主窗口:
从 App.xaml 中删除 StartupUri
启动应用程序并初始化资源后显示 SplashScreen。经过一段(当前固定的)延迟后,关闭 SplashScreen 并显示主窗口:
Tell the SplashScreen that MainWindow is its parent window. When a child window loses focus, its parent gets the focus. If there is no parent, the window manager decides.splashScreen.Show(mainWindow);
EDIT:
I just found out that there's a SplashScreen class. Looks like you use that class and not just a normal Form as I assumed.
So, I just made a simple WPF app with a SplashScreen and for me the mentioned effect didn't happen. The main window didn't lose focus.
I would suggest you to comment potions of your app's initalization code out until the flashing stops. Then you have a starting point for more research why the focus is lost.
EDIT2:
Without knowing your code I tried to reproduce the phenomenon and it wasn't too hard. Whatever I tried, the focus change always happened when the main window was already shown and had focus.
So the best solution I see is to manually show the main window after calling the splash screen's Close() method:
Remove the StartupUri from App.xaml
Show the SplashScreen after starting the app and initializing ressources. After a (currently fixed) delay close the SplashScreen and show the main window:
使用 ILSpy,我发现
SplashScreen.Close
方法在某个时刻调用SetActiveWindow
,导致 slpash 屏幕窗口在开始关闭时变为活动状态。 (至少在 .NET 4.0 中是这样。)我在调用SplashScreen.Close
之后添加了对MainWindow.Focus
的调用,这解决了问题。否则,我只能看到主窗口如何仅在淡出动画发生期间处于非活动状态。此外,当主窗口加载时,我会显示一个模式对话框窗口,并且它保持活动状态。但是,当该对话框关闭时,主窗口将不再聚焦,而是最终进入 Visual Studio 窗口或启动我的应用程序的任何窗口。从上面插入
Focus
调用也有助于解决这种情况。顺便说一句,这里有一篇很好的文章,解释了如何手动使用
SplashScreen
类而不是项目文件选项:http://tech.pro/tutorial/822/wpf-tutorial-using-splash-screens-in-sp1这是我的应用程序中的一些代码:
在 App.xaml.cs 中:
在我的主窗口 ViewModel 的 Init 命令中(主窗口已经完全可见):
Using ILSpy, I found that the
SplashScreen.Close
method callsSetActiveWindow
at some point, causing the slpash screen window to become active in the moment it starts closing. (At least in .NET 4.0.) I added a call to myMainWindow.Focus
just after callingSplashScreen.Close
, and that resolves the issue.Otherwise, I could see how the main window was inactive only during the time that the fadeout animation took. Additionally, I show a modal dialog window when the main window has loaded, and this remains active. But when that dialog is closed, the main window wouldn't focus anymore and instead I'll end up in the Visual Studio window or whatever started my application. Inserting the
Focus
call from above also helps in this situation.BTW, here's a good article that explained me how to use the
SplashScreen
class manually instead of the project file option: http://tech.pro/tutorial/822/wpf-tutorial-using-splash-screens-in-sp1This is some code from my application:
In App.xaml.cs:
In my main window ViewModel's Init command (the main window is already completely visible):