2011-04-25 63 views
3

嗨,我有一個應用程序,其中一個作業將轉換爲Excel並將所有記錄傳遞給數據庫。在WPF中將BackgroundWorker與ProgressBar結合使用

所以這需要一點時間,因爲它會超過7000行,我會得到並插入數據庫。

所以,因爲這項工作需要一點時間,超過3分鐘,我想用ProgressBar來報告這項工作的進度。

因此,如果我在創建的類中執行此作業,我如何使用backgroundWorker向我的情況下的progessBar報告進度?

我的目標是準確的進展如何進展的百分比,以及如何使用所有這些東西來報告進度。我從來沒有與背景工作者合作過。

我認爲,這只是一個提示,也許不錯,我首先得到excel中的行數,將該數字設置爲ProgressBar中的某個Maxvalue,然後對每個Row或間隔我報告進展情況。

這可能嗎?我該怎麼做?

回答

4

我喜歡使用ProgressBars的綁定(以及幾乎所有可能的地方),因爲這樣你不必擔心dispatching to the UI thread

基本上你創建了一些實現INotifyPropertyChanged的類,並且你可以綁定你的ProgressBar進度屬性。例如

public class Task : INotifyPropertyChanged 
{ 
    private int _progress = 0; 
    public int Progress 
    { 
     get { return _progress; } 
     private set 
     { 
      if (_progress != value) 
      { 
       _progress = value; 
       OnPropertyChanged("Progress"); 
      } 
     } 
    } 

    public Task(ref ProgressChangedEventHandler progressChangedEvent) 
    { 
     progressChangedEvent += (s, e) => Progress = e.ProgressPercentage; 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    private void OnPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

此類使用在構造函數中的事件,如果引發將更新任務的進度,但你可以處理你喜歡的任何方式,例如進度變化一種方法或使Progress屬性爲public,以便您可以任意更改它。


用例:

<ProgressBar Minimum="0" Maximum="100" Height="20" 
      Value="{Binding UpdateTask.Progress, Mode=OneWay}"/> 
// The event that should be raised when a progress occurs. 
private event ProgressChangedEventHandler UpdateProgressChanged; 

// The task the ProgressBar binds to. 
private readonly Task _updateTask; 
public Task UpdateTask 
{ 
    get { return _updateTask; } 
} 

public MainWindow() 
{ 
    // Instatiate task, hooking it up to the update event. 
    _updateTask = new Task(ref UpdateProgressChanged); 
} 

private void OnUpdateProgressChanged(int progressPercentage) 
{ 
    if (UpdateProgressChanged != null) 
    { 
     UpdateProgressChanged(this, new ProgressChangedEventArgs(progressPercentage, null)); 
    } 
} 

// Simple progress simulation 
private void Button1_Click(object sender, RoutedEventArgs e) 
{ 
    int progress = 0; 
    DispatcherTimer timer = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(0.5) }; 
    timer.Tick += (sSub,eSub) => 
    { 
     progress++; 
     // Raise progress changed event which in turn will change 
     // the progress of the task which in turn will cause 
     // the binding to update which in turn causes the value 
     // of the ProgressBar to change. 
     OnUpdateProgressChanged(progress); 
     if (progress == 100) 
     { 
      timer.Stop(); 
     } 
    }; 
    timer.Start(); 
} 
+0

好的,如果我想要將進度條綁定到進度條上,我使用Progress屬性,對不對?你能舉一個將進度條綁定到這個屬性的例子嗎? – Miguel 2011-04-25 02:34:46

+0

增加了一個示例,也修復了任務類中的錯誤,構造函數需要通過引用('ref'關鍵字)獲取事件。 – 2011-04-25 03:13:29

+0

由於某種原因,ProgressBar不會更新其值... – Miguel 2011-04-25 07:40:04

0

下面是一個background worker with progress的示例。

但是,仔細檢查以確保BGW在您的情況下可以正常工作。如果您通過COM interop控制Excel,則可能需要STA線程(並且BGW是MTA線程,而不是STA)。

如果是這樣的話,你需要使用一個TaskSTA scheduler,還是自己手動Thread(我強烈建議Task爲基礎的方法)。

+1

是我使用COM互操作。所以你所說的任務方法就是在後臺工作者中提到的一個進度鏈接,對嗎? – Miguel 2011-04-25 02:13:35

+0

是的,除非你必須使用我鏈接到的'StaTaskScheduler'。 – 2011-04-25 02:43:05