2010-10-08 50 views
1

我的BackgroundWorker放在UserControl中有問題。 我的WPF應用程序在左側導航,每個條目加載自己的UserControl,用戶可以在其中生成PDF文件。BackgroundWorker:在完成的事件中啓用/禁用按鈕在用戶控件之間切換後不工作

由於PDF的創建需要一些時間,我已經實現了BackgroundWorker這個工作,另外我禁用了一些按鈕並顯示一個進度條。 在RunWorkerCompleted事件中,我重置按鈕的狀態並隱藏進度條。

儘管存在一種情況,但所有這些工作都很好: 在創建PDF時,用戶可以在UserControl之間切換,並且如果他返回到開始作業的控件,控件應該顯示進度條並按鈕被禁用。 爲了達到這個目的,我在UserControl上加了一個變量(isProcessing)。

一個控制的構造我有這樣的:

 // Check if a current process is running, if so: handle button/progressbar visibility 
     if (_isProcessing) 
     { 
      _stkProgressBar.Visibility = Visibility.Visible; 
      progressBar1.IsIndeterminate = true; 

      // Disabling the buttons here is just working with a hack in 
      // the "Button_IsEnabledChanged" event. 
      btnDaten.IsEnabled = false; 
      btnBericht.IsEnabled = false; 
      this.Cursor = Cursors.Wait; 
     } 
     else 
     { 
      _stkProgressBar.Visibility = Visibility.Hidden; 
     } 

啓用/禁用有剛剛工作,因爲這個骯髒的黑客的按鈕:

private void btnDaten_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e) 
    { 
     //HACK: We want to disable the report buttons if a report execution is running. 
     //  Disabling the buttons in the Load Event of the control isn't working 
     if (_isProcessing && (bool)e.NewValue) 
     { 
      btnDaten.IsEnabled = false; 
      btnBericht.IsEnabled = false; 
     } 
    } 

現在,如果作業正在運行,並用戶在控件之間切換,處理控制的狀態很好。但是,如果作業結束並且PDF已準備就緒,則無法啓用按鈕,並且進度條也保持可見。該代碼被放置在RunWorkerCompleted事件:

void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     // This is not working if the user switches between the controls 
     _isProcessing = false; 
     this.Cursor = Cursors.Arrow; 
     _stkProgressBar.Visibility = Visibility.Hidden; 
     btnDaten.IsEnabled = true; 
     btnBericht.IsEnabled = true; 
    } 

我調試它,看到的按鈕得到正確的輸入,因此應該被啓用,但沒有任何反應。如果用戶停留在開始作業的控件中,則按鈕和進度條的狀態將被正確重置。

+0

在調試過程中您注意到執行控制是否達到'worker_RunWorkerCompleted'? – Nayan 2010-10-08 14:21:29

+0

我在'worker_RunWorkerCompleted'中設置了一個斷點,並且已經達到了。 – danjov 2010-10-08 14:23:35

回答

3

是的,用戶控件之間的切換是這裏的問題。當您切換回切換時,您將創建一個新的控件實例。這創建了BackgroundWorker的一個新實例。其中有一個RunWorkerCompleted事件處理程序與實際運行的BGW沒有關聯。

您的代碼中存在另一個錯誤,當原始BGW實例完成作業並設置(現在不可見)控件屬性時,這應該使ObjectDisposedException崩潰。您在用戶控件之間切換時忘記調用Dispose()。不太清楚WPF中是如何完成的,但是在Winforms中是不可避免的泄漏。

只要你想支持切換,你將會有不同的改變。 BGW實例需要與用戶控制實例分開,以便能夠在交換機上運行。相當痛苦的是,當控件被創建和處置時,你必須連接和斷開事件,你肯定需要重寫Dispose()方法並且不要忘記調用它。如果你只允許它一次一個地運行的工作,那麼使BGW變得靜態是有道理的。這應該是正常的。堆疊用戶控件,以便您只創建一次是Q & D修復程序。

+0

謝謝你的回答。這聽起來很有希望,我會嘗試這種方法並在這裏報告我的結果。 – danjov 2010-10-08 14:47:16

+0

我試過你的方法,我很成功,非常感謝你! – danjov 2010-10-13 09:47:48

相關問題