This is my first post, here it goes... I have a class called Job that connects to multiple tables in a database in the constructor and gets an item from each table. The database is being accessed through SOAP web services. The object is created from a button click. When the class is created in main, a search string and a custom progress bar GUI element with text are passed in.
The progress bar is a custom user control and has an Update() method to update the message text and the progress.
I have tried multiple ways to get the GUI (Progress Bar) to update from the constructor, and found this post (How to use WPF Background Worker) to be very helpful, however the GUI is only updating when the whole method is finished.
I have tried removing the methods from the constructor of the Job class and calling them from the main thread and updating the GUI in between method calls, I have tried using dispatcher to update the GUI and even awaiting them as a task. I also tried updating the values of the Custom Control directly. Still, the GUI only seems to update after the search method is complete.
Is there a better way to go about this? Am I doing too much in the constructor of the Job class? Even before the object is created the GUI doesn't seem to be updating.
private async void AddMasterJob_Click(object sender, RoutedEventArgs e)
{
SearchMethod();
}
//Search method is used in multiple places.
private async void SearchMethod()
{
//This does not change the GUI until the whole method is complete.
await Task.Run(() => CurrentProgressControl.Visibility = Visibility.Visible);
await Task.Run(() => CurrentProgressControl.BringIntoView());
//Checks if record exists during constructor
var tempJob = new Job(SearchBox.Text, CurrentProgressControl);
//Only assign _masterJob if search was successful.
if (tempJob.MasterJob != null)
{
//Try updating the GUI fields directly
await Task.Run(() => CurrentProgressControl.progressBar.Value = 25);
await Task.Run(() => CurrentProgressControl.label.Content = "Getting SubJobs");
//Gets the subjobs and creates an array of subjob objects
tempJob.GetSubJobs();
//Try updating using the update method built into the custom control
CurrentProgressControl.Update("Getting Planning Lines and Ledger Entries.", 45);
//Get the planning lines and ledger entries
tempJob.GetPlanningLinesandLedgerEntries();
CurrentProgressControl.Update("Creating the Estimate Line List.", 60);
//Combines Subjobs, Planning Lines, and Ledger Entries
//Calls CalculateTable(_tableLines)
tempJob.CreateEstimateLineList();
CurrentProgressControl.Update("Separating into Labor and Material.", 75);
//Populate _laborLines and _materialLines
tempJob.SeparateTableLines(tempJob.TableLines);
CurrentProgressControl.Update("Creating SubTotals.", 85);
//Insert the subtotal Lines
tempJob.CreateSubtotalLines(tempJob.LaborLines);
tempJob.CreateSubtotalLines(tempJob.MaterialLines);
CurrentProgressControl.Update("Calculating Totals.", 95);
//Calculate the total estimate column and subtotal lines
tempJob.CalculateTable(tempJob.MaterialLines);
tempJob.CalculateTable(tempJob.LaborLines);
//Calculate the totals for the whole Job
tempJob.CalculateTotals();
CurrentProgressControl.Update("Completed Successfully.", 100);
_masterJob = tempJob;
RaisePropertyChanged("MasterJob");
}
}
The GUI updates after the searchMethod is complete, but not before. Some of the constructor methods inside of the search method take a several seconds so I would expect the GUI to update multiple times, but instead just one update that says complete.