62684


お世話になります。

C#(.Net
Framework)2019にて、アプリケーションを作っています。長い処理をさせているときにスプラッシュスクリーンを表示させようと、ラベルとPictureBoxを使用して簡単なSSを作ったのですが、いざ表示させて  
メインの処理に入ると、SSの描画が終わらないらしく、ラベルとPictureBoxの部分が透過して  
表示され、処理が終了するまでそのままの状態で表示されてしまいます。

[![表示させたいSSはこれです。](https://i.stack.imgur.com/s3ZNa.jpg)](https://i.stack.imgur.com/s3ZNa.jpg)  
↑これが作成したSSです。

[![画像の説明をここに入力](https://i.stack.imgur.com/IKq4d.jpg)](https://i.stack.imgur.com/IKq4d.jpg)  
↑実際に表示させると、コントロールの部分が透過しています。

スクリーンショットでも撮れなかったので、エディタ上のデザインを表示させていますが、実際には  
上記画像の黒い部分が抜けている状態です。

考え方では、SSが描画が終了したらメインの処理を行えばよいと思うのですが、どうすればよいでしょうか。

ちなみに、SSはShowDialogではなく、Showで表示させ、同じメソッド内で表示し、処理が完了したら閉じるようになっています。

下記がコードです。

[code]

    private void reload()
    {
        FolderBrowserDialog fbd = new FolderBrowserDialog();
        fbd.Description = "ファイルを検索するルートフォルダを選択してください。";
        if (fbd.ShowDialog() != DialogResult.OK)
        {
            return;
        }
    
        string stSelectedPath = fbd.SelectedPath;
        if (!System.IO.Directory.Exists(stSelectedPath))
        {
            MessageBox.Show("指定されたフォルダは存在しません。", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
            return;
        }
    
        SplashScreen ss = new SplashScreen();　　　　// ここで表示するも、きれいに出ない。
            ss.Show(this);
    
        if (!PlayListModel.reload(stSelectedPath))
        {
            ss.Close();
            ss = null;
            MessageBox.Show("データベースへの登録に失敗しました。", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
            return;
        }
    
        ss.Close();
        ss = null;
    
        this.review();
    
        MessageBox.Show("読み込みが完了しました。", AppName, MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
    
[/code]

よろしくお願いいたします。


CC BY-SA 4.0
2020-01-31T08:31:58.950
62680
2020-01-31T15:37:40.657
2020-01-31T08:40:56.480
3060
9374
question
c# form
C# スプラッシュウインドウを作り表示させても、きれいに表示されない


async/await 構文を使うのが良いかなと思います。  
`SplashScreen`
の描画完了を待っているわけではなく、描画と同時進行で読み込み処理を行います。読み込み処理中にUIを操作することもできます。不都合な場合は `Enabled`
を `false` にするとよいかもしれません。

[code]

    async void LoadButton_Click(object sender, EventArgs e)
    {
        try
        {
            await Reload();
        }
        catch (Exception ex)
        {
            // ...
            Application.Exit();
        }
    }
    
    async Task Reload()
    {
        var ss = new SplashScreen();
        ss.Show(this);
    
        var succeded = await Task.Run(() => HeavyTask());
        ss.Close();
    
        if (!succeded)
        {
            // ...
        }
        // ...
    }
    
[/code]

もしくは `Application.DoEvents`
で描画の完了を強制できるようです。こちらは読み込み処理中にアプリケーションがフリーズしたようになります。あまりに長いとOSから応答なしと判断されるかもしれません。

[code]

    async void LoadButton_Click(object sender, EventArgs e)
    {
        Reload();
    }
    
    async void Reload()
    {
        var ss = new SplashScreen();
        ss.Show(this);
        Application.DoEvents();
    
        var succeded = HeavyTask();
        ss.Close();
    
        if (!succeded)
        {
            // ...
        }
        // ...
    }
    
[/code]


CC BY-SA 4.0
2020-01-31T15:37:40.657
62684
2020-01-31T15:37:40.657
20885
62680
answer