しばらく開発から遠ざかっていたのでほぼ初心者です。
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
以上、よろしくお願い致します。
尚、質問をしておきながら誠に勝手ですみませんが、「できるだけ頻繁に確認するつもりですが、少し間が空く時もございます。」大変失礼だと思いますがご容赦ください。
時間の掛かる処理を別スレッドで動作させるようにして
UIスレッドを軽くした方がよいです。
BackgroundWorkerを用いると実装しやすいかと思います。
Form2かTest2かの表示に必要な情報がメモリ外より読込む
ものであればBackgroundWorkerでそれらの情報を読み完了したら
newして読込んだメモリ内の情報を設定すれば良いかと思います。
shuさんありがとうございます。
「FormからForm2」と書きながら、読出しているフォームを「Test2」と書いていました。すいません。下記に修正します。
Using frm As New Form2
frm.ShowDialog(Me) ' Load時に、構築に時間がかかる
End Using
Form2には、複数のコンボがあり、対応するデータをDBの各テーブルから読込んでデータをセットしています。
ここを、BackgroundWorkerで一旦メモリーに読込むということでしょうか?
その内容を、new(Form2の Sub New)で各コンボに代入する・・・
という解釈で良いでしょうか?
すぐに手が付けられませんが、試してみます。
試してもいないのにすみません・・・
説明不足で、意図する内容が伝わっていなかったらすみません。
目標としているのは、「時間のかかる処理を短縮する」もそうですが、「Form2が表示されるまでの間、Form1のスタータスバーに在るプログレスを表示させる」の方に重点を置いています。
このような処理は可能なのでしょうか? 引き続きよろしくお願いします。
> 目標としているのは、「時間のかかる処理を短縮する」もそうですが、「Form2が表示されるまでの間、Form1のスタータスバーに在るプログレスを表示させる」の方に重点を置いています。
BackgroundWorkerを奨める理由は両方にあります。時間短縮にもなりますがプログレス表示をさせる為にも表示用スレッドの処理を軽くしてあげる必要があります。単純なスレッドによるDB読込の処理を行われてもよいとは思いますが
プログレス表示を通知させるのにタイミングが難しくなります。
> その内容を、new(Form2の Sub New)で各コンボに代入する・・・
という解釈で良いでしょうか?
newの中よりは情報を渡す
Public Sub SetData(tbl as DataTable)
End Sub
または
Public Property Tbl as DataTable
のようなものを作ってそれを使用された方が良いかと思います。
shuさん、やさしい解説ありがとうございました。
いただいた内容を参考に、挑戦してみます。
また、行き詰まりましたらお願い致します。ひとまず「解決」とさせていただきます。
ツイート | ![]() |