none
程式寫法 RRS feed

  • 問題

  • 大大您们好,我想請問一下,我要利用progressBar告知使用者目前進度,我將progressBar單獨寫一個表單,再由目前表單呼叫他,可是我發現不知道是不是因為我的寫法問題,progressBar都要等到執行完目前表單的方法(粗體),在progressBar上的時間才會開始計時和顯示目前進度,以下我程式碼,請各位大大給我指教,謝謝
            private Form2 ProgBar;
            private void monthCalendar1_DateSelected(object sender, DateRangeEventArgs e)
            {           
                ProgBar = new Form2();
                ProgBar.Owner = this;
                ProgBar.Show();
                DataUpdate();       //就是等他執行完 form2才會開始計時,可是他們應該是獨立的個別動作,不是這樣嗎      
            }
    //Form2底下的
            private void Form2_Load(object sender, EventArgs e)
            {
                progressBar1.Visible = true;           
                timer1.Interval = 500;
                timer1.Enabled = true;
            }
            private void timer1_Tick(object sender, EventArgs e)
            {
                if (progressBar1.Value == 100)
                {
                    timer1.Enabled = false;
                    this.Close();
                }
                else
                {
                    progressBar1.Value += 10;
                }
            }
     
    2009年4月14日 上午 03:28

解答

  • 小綠兒:
          我用VB 2005測試沒這個現象,很正常啊
          是不是你的DataUpdate函式根本跑不到 0.5秒就結束了?
          我的程式如下
         
          Public Class Form1
        Dim bIsRun As Boolean = False
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            If bIsRun = False Then
                bIsRun = True
                Form2.Owner = Me
                Form2.Show()
                Looping01()
            End If

        End Sub
        Private Sub Looping01()
            Dim i As Integer = 0
            While bIsRun
                Label1.Text = i
                i += 1
                Application.DoEvents()
                System.Threading.Thread.Sleep(100)
            End While
        End Sub

        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            If bIsRun = True Then
                bIsRun = False
            End If
        End Sub
    End Class

    Public Class Form2

     
        Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            ProgressBar1.Visible = True
            Timer1.Interval = 500
            Timer1.Enabled = True

        End Sub

        Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
            If ProgressBar1.Value = 100 Then
                Timer1.Enabled = False
            Else
                ProgressBar1.Value += 10
            End If
             
        End Sub
    End Class

    • 已提議為解答 cmf 2009年4月14日 上午 06:25
    • 已標示為解答 冰糖旋風 2009年4月14日 上午 07:21
    2009年4月14日 上午 03:51
    版主
  • 我剛試了一下,原來是我習慣太好(這樣好像有點自誇!?)
    把程式小改一下
    Private Sub Looping01()
            Dim i As Integer = 0
            While bIsRun
                Label1.Text = i
                i += 1
                ' Application.DoEvents()
                System.Threading.Thread.Sleep(100)
                If i = 50 Then
                    Exit While
                End If
            End While
        End Sub
    把  Application.DoEvents() Remark起來,果然就出現小綠兒的結果
    • 已標示為解答 冰糖旋風 2009年4月14日 上午 07:21
    2009年4月14日 上午 06:22
    版主
  • 個人拙見
    這類問題應該習慣性要用事件處理掉
    像是這個例子
    若是在DataUpdate內利用事件把進度給傳出來
    這樣在Form2的進度Bar就可以有較為明確的進度
    而不是用Timer觸發造個假的進度
    而且也不需要利用DoEvent就可以顯示

    利用DoEvent寫出的類別
    感覺上也較不適用於多執行緒程式
    因為多執行緒程式並不需要DoEvent
    介面就可以正常顯示
    或是說今天介面顯示不是很大的考量
    或根本沒有介面
    反倒是希望越快處理完越好
    這時重用當初用DoEvent寫的類別方法就不太適用
    使用了DoEvent反而讓該方法的處理效率更差

    http://www.dotblogs.com.tw/larrynung/
    • 已提議為解答 cmf 2009年4月14日 上午 07:17
    • 已標示為解答 冰糖旋風 2009年4月14日 上午 07:21
    2009年4月14日 上午 06:37

所有回覆

  • 小綠兒:
          我用VB 2005測試沒這個現象,很正常啊
          是不是你的DataUpdate函式根本跑不到 0.5秒就結束了?
          我的程式如下
         
          Public Class Form1
        Dim bIsRun As Boolean = False
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            If bIsRun = False Then
                bIsRun = True
                Form2.Owner = Me
                Form2.Show()
                Looping01()
            End If

        End Sub
        Private Sub Looping01()
            Dim i As Integer = 0
            While bIsRun
                Label1.Text = i
                i += 1
                Application.DoEvents()
                System.Threading.Thread.Sleep(100)
            End While
        End Sub

        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            If bIsRun = True Then
                bIsRun = False
            End If
        End Sub
    End Class

    Public Class Form2

     
        Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            ProgressBar1.Visible = True
            Timer1.Interval = 500
            Timer1.Enabled = True

        End Sub

        Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
            If ProgressBar1.Value = 100 Then
                Timer1.Enabled = False
            Else
                ProgressBar1.Value += 10
            End If
             
        End Sub
    End Class

    • 已提議為解答 cmf 2009年4月14日 上午 06:25
    • 已標示為解答 冰糖旋風 2009年4月14日 上午 07:21
    2009年4月14日 上午 03:51
    版主
  • 試試在 DataUpdate()  內 加入  Application.DoEvents Method

    EX:


    DataUpdate() 
    {

     
    foreach (string file in files )
            {
                .
                .
                .
                  Application.DoEvents();
                .
                .
                .
                // Call Sleep so the picture is briefly displayed,
                //which will create a slide-show effect.
                System.Threading.Thread.Sleep(1000);
            }


    }

    Cmf.Net (C) 2009
    • 已提議為解答 cmf 2009年4月14日 上午 06:25
    2009年4月14日 上午 03:53
  • 大大您好,我是會出現form2表單,可是progressBar的進度表不會出現,即使我將時間拉到很短也是出現同樣情況,還是因為我電腦關係嗎,謝謝
    2009年4月14日 上午 05:21
  • 有照cmf大說的加上Application.DoEvents嗎?!
    http://www.dotblogs.com.tw/larrynung/
    • 已提議為解答 cmf 2009年4月14日 上午 06:25
    2009年4月14日 上午 05:48
  • 我剛試了一下,原來是我習慣太好(這樣好像有點自誇!?)
    把程式小改一下
    Private Sub Looping01()
            Dim i As Integer = 0
            While bIsRun
                Label1.Text = i
                i += 1
                ' Application.DoEvents()
                System.Threading.Thread.Sleep(100)
                If i = 50 Then
                    Exit While
                End If
            End While
        End Sub
    把  Application.DoEvents() Remark起來,果然就出現小綠兒的結果
    • 已標示為解答 冰糖旋風 2009年4月14日 上午 07:21
    2009年4月14日 上午 06:22
    版主
  • 個人拙見
    這類問題應該習慣性要用事件處理掉
    像是這個例子
    若是在DataUpdate內利用事件把進度給傳出來
    這樣在Form2的進度Bar就可以有較為明確的進度
    而不是用Timer觸發造個假的進度
    而且也不需要利用DoEvent就可以顯示

    利用DoEvent寫出的類別
    感覺上也較不適用於多執行緒程式
    因為多執行緒程式並不需要DoEvent
    介面就可以正常顯示
    或是說今天介面顯示不是很大的考量
    或根本沒有介面
    反倒是希望越快處理完越好
    這時重用當初用DoEvent寫的類別方法就不太適用
    使用了DoEvent反而讓該方法的處理效率更差

    http://www.dotblogs.com.tw/larrynung/
    • 已提議為解答 cmf 2009年4月14日 上午 07:17
    • 已標示為解答 冰糖旋風 2009年4月14日 上午 07:21
    2009年4月14日 上午 06:37
  • 謝謝各位大大幫助,我也已經解決了,謝謝
    2009年4月14日 上午 07:21