I am using a wpf UserControl to replace text in files in selected drawing files of AutoCAD. The wpf control is to display a status (ProgressBar) indicating the number of files processed at any given time. So I put up the following code, but the ProgressBar simply does not show any progress. Here is the part of relevant code.
XAML:
<ProgressBar HorizontalAlignment="Stretch" Name="pgrSearch" Minimum="0" Maximum="{Binding Path=ProgressBarMaximum}"
Value="{Binding Path=ProgressBarCurrent}" Height="20" Margin="10" />
CodeBehind:
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
}
Why doesn’t the ProgressBar update itself when the ProgressBarCurrent is incremented as indicated above in code.
Edit:
In Order to process the ProgressBar update code on UI thread, I changed my code to use BackgroundWorker.ReportProgress() as given under.
CodeBehind for UserControl:
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();
}
The BackgroundWorker:
public void ReplaceTextInFiles(BackgroundWorker workerThread, string searchText, string replaceText, List<string> filesList, string reportPath,
bool MatchCase, bool MatchSubstring) {
...
workerThread.ReportProgress(50);
}
Still the ProgressBar doesn’t update itself.
I created a test project with your initial code. After a while I found that you have declared the ProgressBarCurrent property as private. After changing to public it worked for me. So it doesn’t seem necessary to update the property on the UI thread. It looks like a Dispatcher.Invoke call is made internally when reading back the updated property value.