2011-10-07 116 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 
}