SplashScreen.Close()窃取了MainWindow的焦点

时间:2011-10-07 14:31:23

标签: .net wpf focus splash-screen

当SplashScreen关闭时(手动或通过AutoClose),它会在淡出动画期间窃取MainWindow的焦点。这导致主窗口的标题从活动切换到非活动(灰色)到活动。是否有任何技巧可以防止SplashScreen窃取焦点?

2 个答案:

答案 0 :(得分:5)

告诉SplashScreen MainWindow是其父窗口。当子窗口失去焦点时,其父窗口会获得焦点。如果没有父级,则窗口管理器决定。

<击> splashScreen.Show(主窗口);

修改

我刚刚发现有一个SplashScreen课程。看起来你使用那个类而不仅仅是我假设的普通表格。

所以,我刚用SplashScreen制作了一个简单的WPF应用程序,对我来说,上面提到的效果并没有发生。主窗口没有失去焦点。

我建议你评论应用程序的初始化代码的药水,直到闪烁停止。然后你有了一个起点,可以进一步研究为什么失去焦点。

<强> EDIT2

在不知道你的代码的情况下,我试图重现这种现象并且并不太难。无论我尝试什么,焦点变化总是在主窗口已经显示并具有焦点时发生。

所以我看到的最佳解决方案是在调用启动画面的Close()方法后手动显示主窗口

  1. 从App.xaml中删除StartupUri

  2. 启动应用程序并初始化资源后显示SplashScreen。在(当前固定的)延迟之后关闭SplashScreen并显示主窗口:


  3. 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
        }
    }
    

答案 1 :(得分:2)

使用ILSpy,我发现SplashScreen.Close方法在某个时刻调用SetActiveWindow,导致slpash屏幕窗口在它开始关闭时变为活动状态。 (至少在.NET 4.0中。)我在调用MainWindow.Focus后刚刚调用SplashScreen.Close,这解决了问题。

否则,我只能在fadeout动画拍摄期间看到主窗口是如何处于非活动状态的。此外,我在主窗口加载时显示模态对话框窗口,并保持活动状态。但是当该对话框关闭时,主窗口将不再聚焦,而是我将最终进入Visual Studio窗口或任何启动我的应用程序。从上面插入Focus来电也有助于解决这种情况。

BTW,这是一篇很好的文章,它解释了如何手动使用SplashScreen类而不是项目文件选项:http://tech.pro/tutorial/822/wpf-tutorial-using-splash-screens-in-sp1

这是我的应用程序中的一些代码:

在App.xaml.cs中:

/// <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();
}

在我的主窗口中ViewModel的Init命令(主窗口已经完全可见):

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
}