I am implementing a ProgressBar that updates after a every finished task (with 5 tasks total). It should update by 20% after each finished task. A button click starts running the tasks, but when it is clicked the progress bar goes from 0% to 100% without updating in between. Thread.Sleep(1000) was added before each increment of the progress value to simulate the time each task will take. I want to get the progress bar working before adding the code for each task.
I've tried adding a AvaloniaPropertyChanged event, but it doesn't seem to change the problem.
MainWindow.xaml:
<ProgressBar Name="RunProgress" Value="{Binding Progress}" IsIndeterminate="False" Minimum="0" Maximum="100" Height="30"/>
<TextBlock Text="{Binding ElementName=RunProgress, Path=Value, StringFormat={}{0:0}%}" HorizontalAlignment="Center" VerticalAlignment="Center" />
MainWindow.xaml.cs:
//boolean variables for whether or not that process is completed (false if not done, true if done)
bool MasterLimitsRead = false;
bool MasterOrganized = false;
bool LimitsOrganized = false;
bool RemovedFailed = false;
bool OutputCreated = false;
//holds descriptions of the 5(+1) operations the program runs through including description for Done
string[] operation =
{
"Reading the master and limits file text",
"Organizing the master data",
"Organizing the limits",
"Identifying and removing failed devices",
"Creating the output",
"Done"
};
context.CurrentOp = operation[0];
Thread.Sleep(1000);
MasterLimitsRead = true;
if(MasterLimitsRead == true)
{
context.Progress += 20;
context.CurrentOp = operation[1];
}
Thread.Sleep(1000);
MasterOrganized = true;
if(MasterOrganized == true)
{
context.Progress += 20;
context.CurrentOp = operation[2];
}
Thread.Sleep(1000);
LimitsOrganized = true;
if(LimitsOrganized == true)
{
context.Progress += 20;
context.CurrentOp = operation[3];
}
Thread.Sleep(1000);
RemovedFailed = true;
if(RemovedFailed == true)
{
context.Progress += 20;
context.CurrentOp = operation[4];
}
Thread.Sleep(1000);
OutputCreated= true;
if(OutputCreated== true)
{
context.Progress += 20;
context.CurrentOp = operation[5];
}
MainWindowViewModel.cs:
private string currentOp = string.Empty; //variable to store current operation, initialized to empty string
public string CurrentOp
{
get => currentOp;
set
{
if (value != currentOp)
{
currentOp = value;
OnPropertyChanged();
}
}
}
private string progress = 0; //variable to store ProgressBar value in percent, initialized to 0
public string CurrentOp
{
get => currentOp;
set
{
if (value != currentOp)
{
currentOp = value;
OnPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
if(PropertyChanged != null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Expected: Progress bar should increment from 0% to 100% by 20% after each task is complete (simulated by a 1 second delay by the Thread.Sleep(1000))
Actual: Progress bar starts at 0%, then when button is clicked, halts UI interaction for 5 seconds then updates the progress bar to 100%. I want it to update at every increment of value of progress bar.
By calling Sleep
you are blocking the UI thread. If UI thread is blocked, there won't be any UI updates. To simulate long-running tasks use await Task.Delay(TimeSpan.FromSeconds(1))
instead.