2012-06-19 49 views
0

我正在使用wpf UserControl替換AutoCAD中選定圖形文件中的文本。 wpf控件將顯示一個狀態(ProgressBar),表示在任何給定時間處理的文件數量。所以我提出了以下代碼,但ProgressBar根本沒有顯示任何進度。這是相關代碼的一部分。WPF ProgressBar未更新其進度狀態

XAML:

<ProgressBar HorizontalAlignment="Stretch" Name="pgrSearch" Minimum="0" Maximum="{Binding Path=ProgressBarMaximum}" 
       Value="{Binding Path=ProgressBarCurrent}" Height="20" Margin="10" /> 

代碼隱藏:

public partial class ReplaceUserControl : UserControl, INotifyPropertyChanged { 
    public ReplaceUserControl() { 
     InitializeComponent(); 
     this.DataContext = this; 
    } 
    .... 

    private int _progressBarMaximum; 
    public int ProgressBarMaximum { 
     get { return _progressBarMaximum; } 
     set { _progressBarMaximum = value; RaisePropertyChanged("ProgressBarMaximum"); } 
    } 

    private int _progressBarCurrent; 
    private int ProgressBarCurrent { 
     get { return _progressBarCurrent; } 
     set { _progressBarCurrent = value; RaisePropertyChanged("ProgressBarCurrent"); } 
    } 


    private void ReplaceTextInFiles() { //Called from Button_Click Handler 
     .... 

     ProgressBarMaximum = filesList.Count - 1; 

     SearchReplaceWorker replaceWorker = new SearchReplaceWorker(); //The Work Horse 
     replaceWorker.FileProcessed += new FileProcessedEventHandler(worker_FileProcessed); //Raised by Work Horse when each file is processed 

     BackgroundWorker workerThread = new BackgroundWorker(); //The Background Worker Thread 
     workerThread.DoWork += (o, e) => { 
      replaceWorker.ReplaceTextInFiles(SearchText, ReplaceText, filesList, ReportFolderPath, MatchCase, MatchSubstring); 
     }; 
     workerThread.RunWorkerAsync(); //Start the Background Thread Async 
    } 

    void worker_FileProcessed(object sender, EventArgs e) { 
     ProgressBarCurrent = ProgressBarCurrent + 1; //Update the ProgressBar status 
    } 

爲什麼不進度更新自身時如在上述代碼指示的ProgressBarCurrent遞增。

編輯: 爲了處理在UI線程的進度更新代碼,我改變了我的代碼,使用BackgroundWorker.ReportProgress()根據給定的。

代碼隱藏的用戶控件:

private void ReplaceTextInFiles() { //Called from Button_Click() 
    if (!Directory.Exists(SearchFolderPath)) { 
     MessageBox.Show("Invalid Directory Selected for Search"); 
     return; 
    } 

    if (!Directory.Exists(ReportFolderPath)) { 
     MessageBox.Show("Invalid Directory Selected for Report File"); 
     return; 
    } 

    List<string> filesList = null; 
    try { 
     if (LookInSubFolders) { 
      filesList = Directory.GetFiles(@SearchFolderPath, "*.dwg", SearchOption.AllDirectories).ToList(); 
     } 
     else { 
      filesList = Directory.GetFiles(@SearchFolderPath, "*.dwg", SearchOption.TopDirectoryOnly).ToList(); 
     } 
    } 
    catch (Exception ex) { 
     MessageBox.Show("Error Occurred getting the files list. Contact Admin"); 
    } 

    pgrSearch.Visibility = Visibility.Visible; 
    ProgressBarMaximum = filesList.Count - 1; 

    SearchReplaceWorker replaceWorker = new SearchReplaceWorker(); 

    BackgroundWorker workerThread = new BackgroundWorker(); 
    workerThread.WorkerReportsProgress = true; 
    workerThread.ProgressChanged += (o, e) => { //This event handler gets called correctly. 
     ProgressBarCurrent++; 
    }; 
    workerThread.RunWorkerCompleted += new RunWorkerCompletedEventHandler(workerThread_RunWorkerCompleted); 
    workerThread.DoWork += (o, e) => { 
     replaceWorker.ReplaceTextInFiles(workerThread, SearchText, ReplaceText, filesList, ReportFolderPath, MatchCase, MatchSubstring); 
    }; 
    workerThread.RunWorkerAsync(); 
} 

BackgroundWorker的:

public void ReplaceTextInFiles(BackgroundWorker workerThread, string searchText, string replaceText, List<string> filesList, string reportPath, 
             bool MatchCase, bool MatchSubstring) { 
    ... 
    workerThread.ReportProgress(50); 
} 

仍然進度不更新自身。

+0

我有一些類似的問題的幫助。 http://stackoverflow.com/questions/1890518/wpf-multithreaded-progress-dialog – Joe

+0

它出錯哪裏?你確定worker_FileProcessed被調用了嗎? – ekholm

+0

@ekholm,是的,我沒有調試代碼,它正確地擊中了worker_FileProcessed。 – Jatin

回答

2

我用你的初始代碼創建了一個測試項目。一段時間後,我發現您已宣佈ProgressBarCurrent屬性爲私人。更改爲公開後,它爲我工作。所以似乎沒有必要更新UI線程上的屬性。它看起來像是在回讀更新的屬性值時在內部進行Dispatcher.Invoke調用。

+1

確實這是一個愚蠢的錯誤。 ProgressBarCurrent被錯誤地聲明爲私有。我非常感謝你付出了努力並找到了這個愚蠢的錯誤。 – Jatin

+0

在這種情況下,編譯器警告會很好,儘管我意識到這不是微不足道的...... :) – ekholm