等待進度窗體

 這個問題會讓一些初學者感到困惑,一方面模態窗體在打開之後(Form.ShowDialog).主線程無法繼續執行下面的事務;另一方面,又要在處理事務的時候來同步這個窗體裏面的進度條。這兩件事情都必須做,卻都不能先做...

所以很多人不得不把事務處理寫到模態窗體當中去,這樣可以達到目的,卻造成了代碼結構混亂,而且子窗體無法複用,如果有多個事物,不得不爲每個事務來寫控制窗體。

 這裏我們介紹一種比較直接了當的方法,就是主線程中開啓兩個子線程,一個用於顯示模態窗體,一個用於處理事務, 並同時更新第一個線程中的窗體信息。

 這裏的知識範疇會包含線程的基礎用法,線程和UI之間的交互,以及委託的基本用法。如果你還不瞭解這幾點,可以參考一些其他資料,比如我先前寫過的,在同一窗體中用子線程來控制進度條

 

這裏的應用稍微複雜一些,你可以先用Vs2005新建一個Windows Application,這個application包含兩個窗體,一個Form1,爲主窗體,一個Form2,爲模態子窗體。Form1,中添加Button1,用來開啓測試。Form2中添加進度條ProgressBar1和一個用來取消事務的按鈕Button1。然後把如下代碼貼入測試程序中的兩個form裏面。

Form1,主窗體

using System;
using System.Windows.Forms;

namespace WindowsApplication39
{
    
public partial class Form1 : Form
    
{

        
delegate void dShowForm();
        Form2 frm 
= new Form2();

        
public Form1()
        
{
            
this.InitializeComponent();
        }

        
//顯示窗體
        void ShowForm()
        
{
            
if (this.InvokeRequired)
            
{
                
this.Invoke(new dShowForm(this.ShowForm));
            }

            
else
            
{
                frm.ShowDialog(
this);
            }

        }

        
//控制進度
        void SetProgress()
        
{
            
for (int i = 1; i <= 100; i++)
            
{
                
if (frm.DialogResult == DialogResult.Cancel)
                
{
                    
//判斷取消
                    break;
                }

                
else
                
{
                    
//模擬進度
                    frm.SetProgress(100, i);
                    System.Threading.Thread.Sleep(
50);
                }

            }

        }

        
private void button1_Click(object sender, EventArgs e)
        
{
            
new System.Threading.Thread(new System.Threading.ThreadStart(ShowForm)).Start();
            
new System.Threading.Thread(new System.Threading.ThreadStart(SetProgress)).Start();
        }

    }

}

using System;
using System.Windows.Forms;
namespace WindowsApplication39
{
    
public partial class Form2 : Form
    
{
        
public Form2()
        
{
            InitializeComponent();
        }


        
public delegate void dSetProgress(int total, int current);

        
public void SetProgress(int total, int current)
        
{
            
if (this.InvokeRequired)
            
{
                
try
                
{
                    
this.Invoke(new dSetProgress(this.SetProgress), new object[] { total, current });
                }

                
catch { }
            }

            
else
            
{
                
this.progressBar1.Maximum = total;
                
this.progressBar1.Value = current;
            }

        }


        
private void button1_Click(object sender, EventArgs e)
        
{
            
this.DialogResult = DialogResult.Cancel;
        }

    }

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章