Change this:
_percent = (100 * currentDevice) / TOTAL_DEVICE;
this.Percent = _percent;
To this:
this.Percent = (100 * currentDevice) / TOTAL_DEVICE;
UPDATE #1
As you're binding to the code behind, you do not need INotifyPropertyChanged. Give the control a name and update directly.
Also, you're working directly on the UI thread, so there is no time for the UI to update.
UPDATE #2
Here is a working solution:
<Window x:Class="WpfProgress.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:WpfProgress"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Button Content="RunTask"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Click="ButtonBase_OnClick"/>
<ProgressBar x:Name="MyProgressBar"
Minimum="0" Maximum="100"
Grid.Row="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Width="200"
Height="30"/>
</Grid>
</Window>
... and the code-behind:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
var task = StartProcess();
}
private async Task StartProcess()
{
for (int i = 0; i < 100; i++)
{
await Task.Delay(100).ConfigureAwait(false);
var progress = i;
DispatcherHelper.Execute(() => MyProgressBar.Value = progress);
}
}
}
And the
DispatcherHelper
class to marshall back to the UI thread:
public static class DispatcherHelper
{
public static void Execute(Action action)
{
if (Application.Current is null || Application.Current.Dispatcher is null)
return;
Application.Current.Dispatcher.BeginInvoke( DispatcherPriority.Background, action);
}
}