2011-10-07 81 views
4

当SplashScreen关闭(手动或通过AutoClose)时,会在淡出动画期间窃取MainWindow的焦点。这导致主窗口的标题从活动状态切换到非活动状态(灰色)变为活动状态。有没有什么窍门让SplashScreen免于偷窥?SplashScreen.Close()窃取主窗口的焦点

回答

5

告诉SplashScreen MainWindow是它的父窗口。当一个孩子的窗户失去焦点时,其父母就会获得焦点。如果没有父母,窗口管理员决定。

splashScreen.Show(mainWindow);

编辑

我刚刚发现有一个SplashScreen类。看起来像你使用那个类,而不是像我所想的那样只是一个正常的表单。

所以,我只是用一个SplashScreen做了一个简单的WPF应用程序,对于我来说上述效果没有发生。主窗口没有失去焦点。

我建议你评论你的应用程序的初始化代码的药水,直到闪烁停止。那么你有更多研究为什么失去焦点的起点。

EDIT2

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

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

  1. 从App.xaml中取出的StartupUri

  2. 显示启动应用程序并初始化资源后启动屏幕。之后(目前固定)延迟关闭闪屏和显示主窗口:


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 
    } 
} 
+0

SplashScreen的Show方法不接受Window作为参数。我正在使用WPF的内置SplashScreen对象,它不是一个普通的窗口。 – Muis

+0

是的,看我的编辑。 – VVS

+0

您是否在关闭时指定了淡出延迟?当延迟非常短时,可能不会引起注意? – Muis

2

使用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:

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

在我的主窗口视图模型的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 
}