2011-05-25 29 views
1

ProgressForm類別:C#線程和ShowDialog的問題

public partial class ProgressForm : Form 
    { 
     public int prc = 0, sz; 
     MainForm mf; 

     public ProgressForm(MainForm MF) 
     { 
      InitializeComponent(); 
      mf = MF; 
      sz = 0; 
     } 

     public ProgressForm(int mx) 
     { 
      InitializeComponent(); 
      sz = mx; 
     } 

     public void SetMax(int mx) 
     { 
      sz = mx; 
     } 

     public void StartProgress() 
     { 
      timer1.Enabled = true; 
     } 

     public void IncProgress(int prg) 
     { 
      prc += prg; 
     } 

     private void timer1_Tick(object sender, EventArgs e) 
     { 
      double pos = (double)prc/(double)sz * 100; 
      progressBar.Value = (int)pos; 
     } 

     private void ProgressForm_FormClosing(object sender, FormClosingEventArgs e) 
     { 
      timer1.Enabled = false; 
     } 

     private void cancelBtn_Click(object sender, EventArgs e) 
     { 
      mf.isCanceled = true; 
      this.Close(); 
     } 

     private void ProgressForm_Shown(object sender, EventArgs e) 
     { 
      progressBar.Value = 0; 
      StartProgress(); 
     } 

    } 

MainForm類:

void DeleteFiles() 
      { 
       int x = 0; 
       int cnt = resultList.Count; 
       isCanceled = false; 

       DeleteThreadHandler("beginprogress"); 
       try 
       { 
        DeleteThreadHandler("begindelete"); 
        for (int j = 0; j < cnt; j++) 
        { 
         if (resultList[x].isChecked) 
         { 
          DeleteThreadHandler("progress"); 
          DeleteFile(resultList[x].name, deleteForm.isDeletePermanently); 
          if (File.Exists(resultList[x].name)) 
          { 
           DeleteErrorHandler(resultList[x].name); 
           isError = true; 
          } 
          else 
           resultList.RemoveAt(x); 
         } 
         else 
          ++x; 

         if (isCanceled) 
          break; 
        } 
       } 
       finally 
       { 
        validity(true); 
        DeleteThreadHandler("enddelete"); 
       } 
      } 

      void DeleteErrorHandler(string val) 
      { 
       Action action = null; 

       action =() => 
       { 
        errorReportForm.AddError(val); 
       }; 

       this.BeginInvoke(action); 
      } 

      void DeleteThreadHandler(String title) 
      { 
       Action action = null; 
       if (title == "beginprogress") 
       { 
        action =() => 
        { 

        }; 
       } 
       else 
       if (title == "begindelete") 
       { 
        action =() => 
        { 
         olvVirtual.BeginUpdate(); 
        }; 
       } 
       else 
        if (title == "enddelete") 
        { 
         action =() => 
         { 
          olvVirtual.VirtualListSize = resultList.Count; 
          olvVirtual.EndUpdate(); 
          RefreshStatus(); 
          progressForm.Close(); 
          if (isError) 
           errorReportForm.ShowDialog(); 
         }; 
        } 
       if (title == "progress") 
       { 
        action =() => 
        { 
         progressForm.IncProgress(1); 
        }; 
       } 

       this.BeginInvoke(action); 
      }  


    private void DeleteBtn_Click(object sender, EventArgs e) 
     { 
      int checkedcount = GetCheckedCount(); 
      if (checkedcount == 0) 
      { 
       MessageBox.Show("Please mark at least a file first"); 
       return; 
      } 
      DialogResult dr = new DialogResult(); 
      if (deleteForm == null) 
       deleteForm = new DeleteForm(); 
      dr = deleteForm.ShowDialog(); 
      if (dr == DialogResult.OK) 
      { 
       //if (progressForm == null) 
       progressForm = new ProgressForm(this); 
       progressForm.Text = "Deleting..."; 
       progressForm.SetMax(checkedcount); 

       if (errorReportForm == null) 
        errorReportForm = new ErrorReportForm(); 
       errorReportForm.ClearMemo(); 
       isError = false; 

       Thread t = new Thread(DeleteFiles); 
       t.Start(); 
       progressForm.ShowDialog(); 
      } 
     } 

在progressForm,有一個進度條&定時器,更新進度每500毫秒。 問題是我仍然可以訪問主窗體,我也嘗試BeginInvoke,但都不工作 任何人都知道什麼是錯的?

感謝

編輯:我發現這個爛攤子的來源,這是其中的DeleteFile使用Microsoft.VisualBasic.FileIO.FileSystem.DeleteFile。用非託管代碼替換它後,它工作正常。

+0

我想回答我們想看到DeleteFiles函數... – 2011-05-25 04:46:55

+0

通過「我仍然可以訪問主窗體」,你的意思是ShowDialog不凍結主窗口?你是否嘗試過沒有穿線?看起來問題在別的地方。 – Euphoric 2011-05-25 04:53:11

+0

從你的問題中你不清楚你想達到什麼。守則的意圖很明確。那就是說,你在展示你的表格之前就開始了線程。所以你仍然可以訪問表單。 – crypted 2011-05-25 05:01:25

回答

1

嘗試

progressForm.ShowDialog(this); // assuming this is the main form 
+0

仍然不起作用 – Irwan 2011-05-25 05:05:40

+0

@Irwan也調用ShowDialog的窗體必須打開showDialog,否則您將能夠訪問該窗體 – 2011-05-25 05:12:47

+0

@Mario:如何顯示主窗體爲ShowDialog? – Irwan 2011-05-25 05:40:41

0

很難說這種情況的原因是什麼,但你必須有位調試發現事業的一個更好的機會。

我會嘗試以下;

  • 當您在運行DeleteForm的ShowDialog,這是否表現爲一個DeleteForm模態對話框,也可以靜止點擊下面的形式,而DeleteForm是可見的?如果沒有,當你運行ShowDialog(this)時是否會這樣?調用progressForm.ShowDialog(this)並在DeleteFiles開始處設置一對斷點(1),在(2)行的progressForm.IncProgress(1)中設置幾個斷點(1)。當斷點被擊中,使用即時窗口來檢查progressForm.Owner和progressForm.Modal

而且,你傳遞一個參考當前對象爲進步形式? ProgressForm的構造函數中是否有可能導致這些問題的東西?

另一件需要注意的從MSDN的模式對話框是使用關閉按鈕。 以下來自; http://msdn.microsoft.com/en-us/library/w61zzfwe.aspx

當窗體顯示爲模式 對話框,點擊關閉按鈕 (與窗體的 右上角的X的按鈕)將導致 要隱藏的形式和將DialogResult屬性設置爲 DialogResult.Cancel。與非模態的 表單不同,當用戶單擊 對話框的關閉表單按鈕或設置 DialogResult屬性的值時,.NET Framework不會將Close方法稱爲 。取而代之的是 表單被隱藏,並且可以再次顯示 而不創建 對話框的新實例。由於作爲對話框顯示的對話框 隱藏而不是 已關閉,因此您的應用程序需要更長的表單時,必須調用表單的Dispose 方法。

+0

已更新。 1. DeleteForm在ShowDialog()和ShowDialog(this)上正常運行。 2.這兩個progressForm.Modal返回true,progressForm.Owner在DeleteFiles開始時返回{MyProg.MainForm},而在progressForm.IncProgress(1);返回{MyProg.MainForm,Text:MyProg} – Irwan 2011-05-25 07:39:36

+0

對不起,Irwan,我不確定。我複製了你的代碼並編寫了一個可以正常工作的簡化版本。它引發了一些關於將表單元素作爲可重用的成員變量的擔憂。例如,如果模式對話框通過關閉按鈕關閉,它仍然存在於後臺,所以下次調用時,線程仍在後臺處理。我認爲你會從稍微不同的事情中受益。也許看看使用Observer模式來報告進度,並按照已經建議的方式通過BackgroundWorker執行線程。 – 2011-05-25 14:52:41

+0

有關進度報告的替代實現的示例,請查看類似的內容; - http://msdn.microsoft.com/en-us/library/ff648108.aspx(specfically看題爲 「觀察員在.NET」 文章的後半部分) 或 - HTTP:// stackoverflow.com/questions/4792672/how-to-send-progress-updates-from-a-business-model-class/4828404#4828404 我不是故意暗示這是唯一的出路,但我認爲它更清潔。 – 2011-05-25 14:56:43