Formが表示されるまでプログレスを表示するには?

解決


はなこ  2013-07-23 00:07:41  No: 148206

しばらく開発から遠ざかっていたのでほぼ初心者です。
Form1のステータスバー内にプログレスバーを配置してあります。
このFormからForm2をモーダルで表示させるのですが、Form2内の各コントロールの設定に時間がかかるため、その間プログレスバーを表示させようと考えました。
ちょうどIEがページを表示する間プログレスが表示される様な感じを狙っています。
あちこちの掲示板(スレッドからフォームのコントロールを扱うなど)を参考に、スレッドなるものを使ってみましたが、Form2が表示された後にプログレスが動きます。
いろいろ試してみたのですが、どなたか良い方法をご指導ください。

以下、試してみたコードです。
(VB2008/WindowsXPを使用しています)
  Private Delegate Sub ValDelegate(ByVal Value As Integer)     ' コントロールを扱うためのデリゲート宣言
    Private ProgresUp As New ValDelegate(AddressOf SetValue)    ' デリゲート宣言をデータ型とした変数を作成

   Private Sub Button6_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button6.Click

        ' プログレスバー(ステータスバー内)
        With Me.ToolStripProgressBar1
            '.Style = ProgressBarStyle.Marquee
            '.MarqueeAnimationSpeed = 100
            '.Visible = True
            '---
            .Style = ProgressBarStyle.Blocks
            .Minimum = 0
            .Maximum = 12
            .Step = 1
            .Value = 0
            .Visible = True
        End With
        Application.DoEvents()
        Cursor.Current = Cursors.WaitCursor

        Dim Thread1 As New System.Threading.Thread(New System.Threading.ThreadStart(AddressOf ThreadA))
        Thread1.IsBackground = True
        Thread1.Start()
        Me.Button6.Enabled = False

        '-------------------------------
        Using frm As New Test2
            '※ Form2が表示されたらプログレスを非表示にするため、[Shown]イベントを受け取る処理を追加知る予定です。

      frm.ShowDialog(Me)        ' Load時に、構築に時間がかかる
        End Using

    End Sub

    '// スレッドの本体
    Private Sub ThreadA()
        For idx As Integer = 0 To 100
            Me.Invoke(ProgresUp, New Object() {idx})
            System.Threading.Thread.Sleep(10)
        Next idx
    End Sub

    '// (Delegateするメソッド)
    Private Sub SetValue(ByVal val As Integer)
        If val <= Me.ToolStripProgressBar1.Maximum Then
            Me.ToolStripProgressBar1.Value = val
        End If
    End Sub

以上、よろしくお願い致します。
尚、質問をしておきながら誠に勝手ですみませんが、「できるだけ頻繁に確認するつもりですが、少し間が空く時もございます。」大変失礼だと思いますがご容赦ください。


shu  2013-07-23 18:30:51  No: 148207

時間の掛かる処理を別スレッドで動作させるようにして
UIスレッドを軽くした方がよいです。
BackgroundWorkerを用いると実装しやすいかと思います。

Form2かTest2かの表示に必要な情報がメモリ外より読込む
ものであればBackgroundWorkerでそれらの情報を読み完了したら
newして読込んだメモリ内の情報を設定すれば良いかと思います。


はなこ  2013-07-24 00:36:12  No: 148208

shuさんありがとうございます。
「FormからForm2」と書きながら、読出しているフォームを「Test2」と書いていました。すいません。下記に修正します。
 
 Using frm As New Form2
     frm.ShowDialog(Me)  ' Load時に、構築に時間がかかる
 End Using

 Form2には、複数のコンボがあり、対応するデータをDBの各テーブルから読込んでデータをセットしています。
ここを、BackgroundWorkerで一旦メモリーに読込むということでしょうか?
その内容を、new(Form2の Sub New)で各コンボに代入する・・・
という解釈で良いでしょうか?
すぐに手が付けられませんが、試してみます。

試してもいないのにすみません・・・
説明不足で、意図する内容が伝わっていなかったらすみません。
目標としているのは、「時間のかかる処理を短縮する」もそうですが、「Form2が表示されるまでの間、Form1のスタータスバーに在るプログレスを表示させる」の方に重点を置いています。
このような処理は可能なのでしょうか? 引き続きよろしくお願いします。


shu  2013-07-24 01:35:31  No: 148209

> 目標としているのは、「時間のかかる処理を短縮する」もそうですが、「Form2が表示されるまでの間、Form1のスタータスバーに在るプログレスを表示させる」の方に重点を置いています。

BackgroundWorkerを奨める理由は両方にあります。時間短縮にもなりますがプログレス表示をさせる為にも表示用スレッドの処理を軽くしてあげる必要があります。単純なスレッドによるDB読込の処理を行われてもよいとは思いますが
プログレス表示を通知させるのにタイミングが難しくなります。


shu  2013-07-24 01:46:48  No: 148210

> その内容を、new(Form2の Sub New)で各コンボに代入する・・・
という解釈で良いでしょうか?

newの中よりは情報を渡す

Public Sub SetData(tbl as DataTable)

End Sub

または

Public Property Tbl as DataTable

のようなものを作ってそれを使用された方が良いかと思います。


はなこ  2013-07-24 23:39:20  No: 148211

shuさん、やさしい解説ありがとうございました。

いただいた内容を参考に、挑戦してみます。
また、行き詰まりましたらお願い致します。ひとまず「解決」とさせていただきます。


※返信する前に利用規約をご確認ください。




  


  このエントリーをはてなブックマークに追加