NonSoft

進捗ダイアログ表示サンプル(VB.NET)


 サンプル(ソース/コード)
<このサンプルの概要>
共通で使える進捗ダイアログが1つあると便利なのでサンプルソースを作ってみました。
このサンプルの構成は、メインのフォーム(テスト用)、進捗ダイアログ用のフォーム、
実際に処理を実行するアクセサです。アクセサは100m秒間隔で100回ループし、処
理を実行しているように見せかけています。進捗ダイアログには処理中メッセージと中止
ボタンがあり、中止ボタンをクリックすると中止確認メッセージを表示し、中止する場合
は、メインフォームに中止された事を例外を使って通知します。進捗ダイアログ用のフォ
ームと実際に処理を実行するアクセサの間にはインタフェースを使って汎用的にした方が
良いと思いますが、このサンプルでは省略しています。

★進捗ダイアログ用のフォーム(frmProgress.vb)
''' -----------------------------------------------------------------------------
''' 進捗ダイアログ用のフォーム
''' -----------------------------------------------------------------------------
Public Class frmProgress
    Inherits System.Windows.Forms.Form

#Region " Windows フォーム デザイナで生成されたコード "

    Public Sub New()
        MyBase.New()

        ' この呼び出しは Windows フォーム デザイナで必要です。
        InitializeComponent()

        ' InitializeComponent() 呼び出しの後に初期化を追加します。

    End Sub

    ' Form は、コンポーネント一覧に後処理を実行するために dispose をオーバーライドします。
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    ' Windows フォーム デザイナで必要です。
    Private components As System.ComponentModel.IContainer

    ' メモ : 以下のプロシージャは、Windows フォーム デザイナで必要です。
    'Windows フォーム デザイナを使って変更してください。  
    ' コード エディタを使って変更しないでください。
    Friend WithEvents btnCancel As System.Windows.Forms.Button
    Friend WithEvents Label2 As System.Windows.Forms.Label
    Friend WithEvents Label1 As System.Windows.Forms.Label
    Friend WithEvents tmrProc As System.Windows.Forms.Timer
    Friend WithEvents ProgressBar1 As System.Windows.Forms.ProgressBar
     Private Sub InitializeComponent()
        Me.components = New System.ComponentModel.Container
        Me.btnCancel = New System.Windows.Forms.Button
        Me.Label2 = New System.Windows.Forms.Label
        Me.Label1 = New System.Windows.Forms.Label
        Me.tmrProc = New System.Windows.Forms.Timer(Me.components)
        Me.ProgressBar1 = New System.Windows.Forms.ProgressBar
        Me.SuspendLayout()
        '
        'btnCancel
        '
        Me.btnCancel.Location = New System.Drawing.Point(228, 40)
        Me.btnCancel.Name = "btnCancel"
        Me.btnCancel.Size = New System.Drawing.Size(43, 32)
        Me.btnCancel.TabIndex = 7
        Me.btnCancel.TabStop = False
        Me.btnCancel.Text = "中止"
        '
        'Label2
        '
        Me.Label2.Font = New System.Drawing.Font("MS UI Gothic", 12.0!, _
            System.Drawing.FontStyle.Regular, _
            System.Drawing.GraphicsUnit.Point, CType(128, Byte))
        Me.Label2.Location = New System.Drawing.Point(8, 41)
        Me.Label2.Name = "Label2"
        Me.Label2.Size = New System.Drawing.Size(262, 28)
        Me.Label2.TabIndex = 6
        Me.Label2.Text = "しばらくお待ちください。"
        Me.Label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter
        '
        'Label1
        '
        Me.Label1.Font = New System.Drawing.Font("MS UI Gothic", 12.0!, _
            System.Drawing.FontStyle.Regular, _
            System.Drawing.GraphicsUnit.Point, CType(128, Byte))
        Me.Label1.Location = New System.Drawing.Point(8, 9)
        Me.Label1.Name = "Label1"
        Me.Label1.Size = New System.Drawing.Size(262, 28)
        Me.Label1.TabIndex = 5
        Me.Label1.Text = "処理中です。"
        Me.Label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter
        '
        'tmrProc
        '
        '
        'ProgressBar1
        '
        Me.ProgressBar1.Location = New System.Drawing.Point(7, 80)
        Me.ProgressBar1.Name = "ProgressBar1"
        Me.ProgressBar1.Size = New System.Drawing.Size(264, 23)
        Me.ProgressBar1.TabIndex = 8
        '
        'frmProgress
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 12)
        Me.ClientSize = New System.Drawing.Size(280, 112)
        Me.ControlBox = False
        Me.Controls.Add(Me.ProgressBar1)
        Me.Controls.Add(Me.btnCancel)
        Me.Controls.Add(Me.Label2)
        Me.Controls.Add(Me.Label1)
        Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
        Me.Name = "frmProgress"
        Me.ShowInTaskbar = False
        Me.Text = "処理中"
        Me.ResumeLayout(False)

    End Sub

#End Region

    ' 処理オブジェクト
    Public _objAccessor As clsAccessor
    ' 例外オブジェクト
    Public _objException As Exception
    ' 完了フラグ
    Private _endFlag As Boolean

    ''' -----------------------------------------------------------------------------
    ''' 処理開始指令
    ''' -----------------------------------------------------------------------------
    Public Sub StartProc()
        tmrProc.Interval = 1
        tmrProc.Enabled = True
        ShowDialog()
    End Sub

    ''' -----------------------------------------------------------------------------
    ''' 処理開始タイマー
    ''' -----------------------------------------------------------------------------
    Private Sub tmrProc_Tick( _
        ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles tmrProc.Tick
        tmrProc.Enabled = False
        Try
            _objAccessor.Dispatcher()
        Catch ex As Exception
            _objException = ex
        Finally
            _endFlag = True
            Me.Close()
        End Try
    End Sub

    ''' -----------------------------------------------------------------------------
    ''' 中止ボタンクリック
    ''' -----------------------------------------------------------------------------
    Private Sub btnCancel_Click( _
        ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles btnCancel.Click
        If _endFlag = False Then
            If MsgBox("中止します。宜しいですか? ", _
                    MsgBoxStyle.Question Or MsgBoxStyle.YesNo Or _
                                            MsgBoxStyle.DefaultButton2, _
                    "中止確認") = MsgBoxResult.No Then
            Else
                _objAccessor.Cancel()
            End If
        End If
    End Sub
End Class

★実際に処理を実行するアクセサ(clsAccessor.vb)
''' -----------------------------------------------------------------------------
''' 実際に処理を実行するアクセサ
''' -----------------------------------------------------------------------------
Public Class clsAccessor

    Public objProgr As frmProgress          ' 進捗ダイアログフォーム
    Public strPara1 As String               ' パラメタ1
    Public strPara2 As String               ' パラメタ2

    Private _Cancel As Boolean              ' キャンセルフラグ
    Sub New()    End Sub
    ''' -----------------------------------------------------------------------------
    ''' 処理開始指令(処理振り分け)
    ''' -----------------------------------------------------------------------------
    Public Sub Dispatcher()
        _Cancel = False
        Execute()
    End Sub

    ''' -----------------------------------------------------------------------------
    ''' キャンセル指令
    ''' -----------------------------------------------------------------------------
    Public Sub Cancel()
        _Cancel = True
    End Sub

    ''' -----------------------------------------------------------------------------
    ''' 処理実行
    ''' -----------------------------------------------------------------------------
    Public Sub Execute()
        Try
            ' 処理実行&終了待ち
            Dim i As Integer
            For i = 1 To 100
                If _Cancel Then
                    ' 中止例外をスロー
                    Throw New Exception("Cancel")
                End If
                ' 進捗表示
                objProgr.ProgressBar1.Value = i
                ' ダミーの処理
                System.Threading.Thread.Sleep(100)
                ' OSイベント処理
                Application.DoEvents()
            Next
        Catch ex As Exception
            Throw ex
        End Try

    End Sub
End Class

★メインのフォーム(テスト用)(frmMain.vb)
''' -----------------------------------------------------------------------------
''' メインのフォーム(テスト用)
''' -----------------------------------------------------------------------------
Public Class frmMain
    Inherits System.Windows.Forms.Form

#Region " Windows フォーム デザイナで生成されたコード "

    Public Sub New()
        MyBase.New()

        ' この呼び出しは Windows フォーム デザイナで必要です。
        InitializeComponent()

        ' InitializeComponent() 呼び出しの後に初期化を追加します。

    End Sub

    ' Form は、コンポーネント一覧に後処理を実行するために dispose をオーバーライドします。
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    ' Windows フォーム デザイナで必要です。
    Private components As System.ComponentModel.IContainer

    ' メモ : 以下のプロシージャは、Windows フォーム デザイナで必要です。
    'Windows フォーム デザイナを使って変更してください。  
    ' コード エディタを使って変更しないでください。
    Friend WithEvents Button1 As System.Windows.Forms.Button
     Private Sub InitializeComponent()
        Me.Button1 = New System.Windows.Forms.Button
        Me.SuspendLayout()
        '
        'Button1
        '
        Me.Button1.Location = New System.Drawing.Point(63, 32)
        Me.Button1.Name = "Button1"
        Me.Button1.Size = New System.Drawing.Size(168, 40)
        Me.Button1.TabIndex = 0
        Me.Button1.Text = "処理中ダイアログ表示"
        '
        'frmMain
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 12)
        Me.ClientSize = New System.Drawing.Size(292, 102)
        Me.Controls.Add(Me.Button1)
        Me.Name = "frmMain"
        Me.Text = "frmMain"
        Me.ResumeLayout(False)

    End Sub

#End Region

    ''' -----------------------------------------------------------------------------
    ''' 処理開始ボタンクリック
    ''' -----------------------------------------------------------------------------
    Private Sub Button1_Click( _
        ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles Button1.Click
        Try
            ' 処理中ダイアログ表示
            Dim objAcc As New clsAccessor
            Dim objDlg As New frmProgress
            objAcc.objProgr = objDlg
            objAcc.strPara1 = "1"
            objAcc.strPara2 = "2"
            objDlg._objAccessor = objAcc
            objDlg.StartProc()

            ' 例外処理
            If objDlg._objException Is Nothing = False Then
                If objDlg._objException.Message = "Cancel" Then
                    MsgBox("処理を中止しました。 ", , "処理中止")
                Else
                    Throw objDlg._objException
                End If
            Else
                MsgBox("処理を完了しました。 ", , "処理完了")
            End If
        Catch ex As Exception
            Throw ex
        Finally
        End Try
    End Sub
End Class