.net SplashScreen.Close()窃取主窗口的焦点
当SplashScreen关闭(手动或自动关闭)时,它会在淡出动画期间窃取主窗口的焦点。这将导致主窗口的标题从活动切换到非活动(灰色)再切换到活动。有什么办法可以防止SplashScreen窃取焦点吗?告诉SplashScreen主窗口是它的父窗口。当子窗口失去焦点时,其父窗口将获得焦点。如果没有父对象,则由窗口管理器决定 splashScreen.Show(主窗口); 编辑: 我刚发现有一门课。看起来你使用的是那个类,而不是我假设的普通形式 所以,我只是制作了一个简单的WPF应用程序和一个SplashScreen,对我来说,上面提到的效果并没有发生。主窗口没有失去焦点 我建议你将应用程序初始化代码中的药剂注释掉,直到闪烁停止。然后,你就有了一个起点,可以进行更多的研究,了解为什么会失去重点 EDIT2: 在不知道你的代码的情况下,我试图重现这种现象,这并不难。无论我怎么做,焦点的改变总是发生在主窗口已经显示并且有焦点的时候 因此,我看到的最佳解决方案是在调用启动屏幕的Close()方法后手动显示主窗口:.net SplashScreen.Close()窃取主窗口的焦点,.net,wpf,focus,splash-screen,.net,Wpf,Focus,Splash Screen,当SplashScreen关闭(手动或自动关闭)时,它会在淡出动画期间窃取主窗口的焦点。这将导致主窗口的标题从活动切换到非活动(灰色)再切换到活动。有什么办法可以防止SplashScreen窃取焦点吗?告诉SplashScreen主窗口是它的父窗口。当子窗口失去焦点时,其父窗口将获得焦点。如果没有父对象,则由窗口管理器决定 splashScreen.Show(主窗口); 编辑: 我刚发现有一门课。看起来你使用的是那个类,而不是我假设的普通形式 所以,我只是制作了一个简单的WPF应用程序和一个S
使用ILSpy,我发现
SplashScreen.Close
方法在某个点调用SetActiveWindow
,导致slpash屏幕窗口在开始关闭时变为活动状态。(至少在.NET 4.0中)在调用SplashScreen.Close之后,我向我的主窗口添加了一个调用。Focus
,这就解决了问题
否则,我可以看到主窗口仅在淡出动画拍摄期间处于非活动状态。此外,当主窗口加载后,我将显示一个模式对话框窗口,并且该窗口将保持活动状态。但是当对话框关闭时,主窗口将不再聚焦,取而代之的是我将进入VisualStudio窗口或任何启动我的应用程序的窗口。在这种情况下,从上面插入Focus
调用也会有所帮助
顺便说一句,这里有一篇很好的文章解释了如何手动使用SplashScreen
类来代替项目文件选项:
这是我的应用程序中的一些代码:
在App.xaml.cs中:
SplashScreen的Show方法不接受窗口作为参数。我正在使用WPF的内置SplashScreen对象,它不是一个正常的窗口。您是否指定了关闭时的淡出延迟?当延迟时间很短时,它可能不会被注意到?@Joshua:没有。你是否试图消除淡出延迟?它解决了焦点问题吗?是的,当您指定零延迟时,主窗口不会失去焦点。但我的问题是如何在淡出动画期间保持焦点,而不是如何禁用它;)谢谢你的时间和研究。我已经使用OnStartup事件来显示SplashScreen。并且.Show有一个“最上面的”标志,它的设计正好使启动屏幕保持在顶部,而您已经显示了主窗口。我的加载代码有两个阶段,为了提高用户的“感知性能”,我已经显示了主窗口,同时继续加载过程的“第二阶段”。如果我需要等待淡出延迟,我的应用程序对最终用户来说似乎加载较慢。
public partial class App : Application
{
const int FADEOUT_DELAY = 2000;
SplashScreen splash = new SplashScreen("splash.jpg");
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
splash.Show(false, true);
var worker = new BackgroundWorker();
worker.DoWork += (sender, ea) =>
{
Thread.Sleep(1000);
splash.Close(new TimeSpan(0, 0, 0, 0, FADEOUT_DELAY));
// you could reduce the delay and show the main window with a nice transition
Thread.Sleep(FADEOUT_DELAY);
Dispatcher.BeginInvoke(new Action(() => MainWindow.Show()));
};
worker.RunWorkerAsync();
MainWindow = new MainWindow();
// do more initialization
}
}
/// <summary>
/// Application Entry Point.
/// </summary>
[STAThread]
public static void Main()
{
splashScreen = new SplashScreen("Splashscreen.png");
splashScreen.Show(false, true);
Thread.Sleep(2000); // For demonstration purposes only!
App app = new App();
app.InitializeComponent();
app.Run();
}
private void OnInitCommand()
{
ConnectDatabase();
App.SplashScreen.Close(TimeSpan.FromMilliseconds(500));
MainWindow.Instance.Focus(); // This corrects the window focus
SomeDialog dlg = new SomeDialog();
dlg.Owner = MainWindow.Instance;
if (dlg.ShowDialog() == true)
{
// Do something with it
}
// Now the main window is focused again
}