5

私の 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() メソッドにロードします。

4

3 に答える 3

6

WPFでのSplashScreenの作成に関するこの MSDN の記事を参照してください。基本的に、表示するイメージをプロジェクトに追加し、ビルド アクションを SplashScreen に設定します。これは、プログラムの起動時に表示され、メイン アプリケーション ウィンドウが表示されると消えます。


System.ComponentModelクラスをインポートして、BackgroundWorkerを使用して Loading Form を表示することもできます。これにより、UI の応答性を維持できます。

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();
    }
}
于 2012-12-12T08:50:50.183 に答える
2

時間のかかるコードはバックグラウンド スレッドに配置する必要があります (ドット ネット フレームワークのバージョンに応じて、BackgroundWorker、Task、または Async Await を使用できます)。

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

また、ロード画面を表示する最良の方法にも注意してください。メインウィンドウにもいくつかのアニメーションを表示できます。フォームを表示することが最善の方法だとは思いません。

于 2012-12-12T08:48:09.767 に答える
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
}
于 2012-12-12T08:47:49.330 に答える