2012-12-12 75 views
4

我在WPF中的應用程序加載外部資源,所以我想在加載程序時顯示加載表單。顯示加載窗口

我試着創建表單,並在加載代碼之前顯示,並在加載結束時關閉。

private void Window_Loaded(object sender, RoutedEventArgs e) 
{ 
    LoadForm lf = new LoadForm(); 
    lf.Visibility = Visibility.Visible; 

    // Al code that delays application loading 

    lf.Close(); 
} 

但我得到的唯一的事情就是加載進度完成時,立即關閉形式顯示。

我認爲我需要使用System.Threading但不能確定。

謝謝。

注意我在Window_Loaded()方法中加載所有應用程序外部資源,而不是在主類方法中加載。

+0

我覺得你在思考線程時處於正確的道路。你應該打開你的表單,並將所有的東西加載到不同的線程中。這樣你的應用程序就能夠響應,並且不會鎖定用戶界面。 –

+0

閃屏如何?這會起作用嗎? –

回答

1

前一段時間我做了一個Loader類,你可以使用它。它顯示了一個窗口,而這樣做你的加載方法中,完成後關閉它,併爲您提供了方法的輸出:

public class Loader<TActionResult>:FrameworkElement 
{ 
    private Func<TActionResult> _execute; 
    public TActionResult Result { get; private set; } 
    public delegate void OnJobFinished(object sender, TActionResult result); 
    public event OnJobFinished JobFinished; 

    public Loader(Func<TActionResult> execute) 
    { 
     if (execute == null) 
      throw new ArgumentNullException("execute"); 

     _execute = execute; 
    } 

    private Window GetWaitWindow() 
    { 
     Window waitWindow = new Window { Height = 100, Width = 200, WindowStartupLocation = WindowStartupLocation.CenterScreen, WindowStyle = WindowStyle.None }; 
     waitWindow.Content = new TextBlock { Text = "Please Wait", FontSize = 30, FontWeight = FontWeights.Bold, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center }; 

     return waitWindow; 
    } 

    public void Load(Window waitWindow = null) 
    { 
     if (waitWindow == null) 
     { 
      waitWindow = GetWaitWindow(); 
     } 
     BackgroundWorker worker = new BackgroundWorker(); 
     worker.DoWork += delegate 
     { 
      Dispatcher.BeginInvoke(new Action(delegate { waitWindow.ShowDialog(); })); 
      Result = _execute(); 
      Dispatcher.BeginInvoke(new Action(delegate() { waitWindow.Close(); })); 
     }; 
     worker.RunWorkerCompleted += delegate 
     { 
      worker.Dispose(); 
      if (JobFinished != null) 
      { 
       JobFinished(this, Result); 
      } 
     }; 
     worker.RunWorkerAsync(); 
    } 
} 

如何使用它:

Loader<TResult> loader = new Loader<TResult>(MethodName); 
loader.JobFinished += new Loader<TResult>.OnJobFinished(loader_JobFinished); 
loader.Load(); 

void loader_JobFinished(object sender, TResult result) 
{ 
    // do whatever you want with your result here 
} 
+0

如何將參數傳遞給MethodName方法? –

2

你應該把你的耗時碼在後臺線程(對,你可以使用BackgroundWorker的,任務或異步等待,這取決於你點.NET Framework版本)

private void Window_Loaded(object sender, RoutedEventArgs e) 
{ 
    LoadForm lf = new LoadForm(); 
    lf.Visibility = Visibility.Visible; 
    //start the time consuming task in another thread 
} 


HeavyTaskCompleteEvent() 
{ 
    lf.Close(); 
} 

也看出來,以顯示加載的最佳方式屏幕。您也可以在主窗口中顯示一些動畫。我不認爲展示形式是最好的方式。

5

你應該看看這篇關於在WPF中創建SplashScreen的MSDN文章。本質上,您將要顯示的圖像添加到您的項目中,並將生成操作設置爲SplashScreen,它會在您的程序啓動時顯示,並在顯示主應用程序窗口時消失。


您也可以嘗試導入System.ComponentModel類,並使用BackgroundWorker顯示您的載表,它可以讓你保留你的用戶界面的響應。

public partial class MainWindow : Window 
{ 
    Window1 splash; 
    BackgroundWorker bg; 
    public MainWindow() 
    { 

     InitializeComponent(); 

     bg = new BackgroundWorker(); 
     bg.DoWork += new DoWorkEventHandler(bg_DoWork); 
     bg.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_RunWorkerCompleted); 

    } 

    void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     splash.Hide(); 
    } 

    void bg_DoWork(object sender, DoWorkEventArgs e) 
    { 
     System.Threading.Thread.Sleep(10000); 
    } 


    private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     splash = new Window1(); 
     splash.Show(); 
     bg.RunWorkerAsync(); 
    } 
} 
+0

謝謝,但首先我有一個窗口來輸入用戶名和密碼(加載速度快),然後,當程序在程序中被加載時,所有的東西都被加載,但是這對我的其他項目沒有Splash窗口很有用。 – FukYouAll

+0

@SteelersMan看看我的編輯使用'BackgroundWorker'幫助 –

+0

謝謝,這是非常有用的,因爲我試圖做,你幫了兩次。非常感謝:) – FukYouAll