Long running tasks in any application make the application or software irresponsive. So to keep the user updated about the running task and also keep the application responsive while long running tasks we can use different kind of loading bar options like:
Etc.
Let's discuss XAML Progress Bar in WPF Apps.
- What is progress Bar?
XAML progress bar represents a controls that indicates that an operation is ongoing. It looks like this.
XAML Progress bar has 2 states
- Determinate
- Indeterminate
Determinate
In this state user will be aware about the amount of operation which has been completed.
Indeterminate
We use this state of progress bar when you don’t sure about the total execution time of lengthy task. See the 2nd last picture to see its shape.
- Getting started with a Simple Example
Open visual studio and make a blank WPF App
- Once you click ok , you'll see and empty application like this
- We need three controls to Implement Progress Bar Control in this app.
- Button
- Progress bar
- Text block
Button to start a lengthy task, 1 label to show time and other to show status
Make a grid and place these controls accordingly.
<Window x:Class="ProgressBarUndefinedTimeWPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ProgressBarUndefinedTimeWPF"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Button Grid.Row="1" x:Name="btn_StartLengthyTask" Click="btn_StartLengthyTask_Click" Width="200" Height="30" >Start Lengthy Task</Button>
<ProgressBar Grid.Row="2" x:Name="pb_LengthyTaskProgress" Margin="10,20" Value="10" ></ProgressBar>
<TextBlock Grid.Row="3" x:Name="lbl_TaskStatus" >Status...</TextBlock>
</Grid>
</Window>
Now we need to understand the Model of Programming known as Event Driven Model. Because we’ll start a background task and time of completion for that task is not known. Whenever that task will complete its processing, it will call a function on UI thread to inform the user that task has completed. And that function reference will be passed to background thread while calling to it as well.
So in order to save a function reference we use Delegates, That delegate will contain the ref of UI function and it will be passed as parameter to background worker function.
So first of all we’ll declare a delegate in our program like below.
Keep in mind we declare delegate in namespace instead of class. And use them inside the classes
Here is the code
public delegate void RefToFunction();
after this we’ll be needed two functions
- One method will be called on Response from background method
- Other method will be used to simulate the long running task, this method will take the first method’s reference as parameter.
Here is the 1st method.
private async Task PerformLengthyTaskAsync(RefToFunction toFunction)
{
for (int i = 0; i < 5; i++)
{
await Task.Delay(1000);
}
toFunction.Invoke();
}
And here you go with the second method:
private void btn_StartLengthyTask_Click(object sender, RoutedEventArgs e)
{
lbl_TaskStatus.Text = "Task in progress...";
pb_LengthyTaskProgress.IsIndeterminate = true;
RefToFunction toFunction = new RefToFunction(OnReponse);
PerformLengthyTaskAsync(toFunction);
}
We’ll invoke the 2nd method from Code behind in button click event.
private void btn_StartLengthyTask_Click(object sender, RoutedEventArgs e)
{
lbl_TaskStatus.Text = "Task in progress...";
pb_LengthyTaskProgress.IsIndeterminate = true;
RefToFunction toFunction = new RefToFunction(OnReponse);
PerformLengthyTaskAsync(toFunction);
}
You need to use following namespaces to work with Tasks.
using System.Threading.Tasks;
Build the project and run it. Once you click the button, Progress will appear for 5 seconds. Once the task is completed. 2ND method will fire up the OnReponse
Method. Where we can change the UI accordingly.