Question:
Hello, I saw several examples on the internet of progressBar in WPF, but none works.
It appears but does not fill the values, in fact it fills the values only after executing the initial method where it is called.
Source code:
public partial class Apresentacao_ProgressBar : Window
{
private BackgroundWorker backgroundWorker1 = new BackgroundWorker();
public Apresentacao_ProgressBar()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(Form1_Shown);
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
}
void Form1_Shown(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i <= 100; i++)
{
backgroundWorker1.ReportProgress(i);
System.Threading.Thread.Sleep(100);
}
}
void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
PBar.Value = e.ProgressPercentage;
}
}
Answer:
1 – BackgroundWorker
is currently somewhat in disuse.
2 – Use MVVM when working with WPF, it was made to work perfectly with this model.
3 – To work the ProgressBar you need its work to be done in another thread ( BackgroundWorker
does this but as I said it's in disuse)
an example follows:
private Task _task;
public string Arquivo
{
get => _arquivo;
set
{
if (value == _arquivo) return;
_arquivo = value;
OnPropertyChanged();
}
}
public double ProgressMax
{
get => _progressMax;
set
{
if (value.Equals(_progressMax)) return;
_progressMax = value;
OnPropertyChanged();
}
}
public double ProgressValue
{
get => _progressValue;
set
{
if (value.Equals(_progressValue)) return;
_progressValue = value;
OnPropertyChanged();
}
}
private void Importar(string arquivo = "")
{
//Minhas verificações e outras coisas que não preciso mostrar
ProgressValue = 0;
//Aqui verifico se o arquivo está ok (no meu projeto o arquivo vem de um download,
// então não preciso verificar aqui se ele existe pois o serviço de download já verifica)
if (string.IsNullOrEmpty(fileName)) return; //fileName é uma variavel com um arquivo a ser importado
try
{
if ((_task != null) && (_task.IsCompleted == false ||
_task.Status == TaskStatus.Running ||
_task.Status == TaskStatus.WaitingToRun ||
_task.Status == TaskStatus.WaitingForActivation))
return; //se já houver um thread para essa variavel _task ele não inicia outro
_task = Task.Factory.StartNew(TratarArquivo); //Inicia o Thread
}
catch (Exception e)
{
ExibirMensagem(Uteis.RetornaMsgErro(e), TipoMensagem.Erro);
}
}
private void TratarArquivo()
{
try
{
ProgressVisibility = true;
var i = 0;
var j = 0;
var dados = LeArquivo(Arquivo);
ProgressMax = dados.Count();
foreach (var linha in dados)
{
ProgressValue = j;
j++;
//Aqui tem várias coisas que são tratadas, nao importa nesse exemplo
}
}
catch (Exception e)
{
ExibirMensagem(Uteis.RetornaMsgErro(e), TipoMensagem.Erro);
}
finally
{
ProgressVisibility = false;
ProgressValue = 0;
}
}
PS: If you don't understand why the properties implement OnPropertyChanged(), find out more about MVVM and INotifyPropertyChanged
PS: This data is from the ImportacaoViewModel
class, I do NOT have any lines added to code behind
PS: If you want a complete, but very simple, example of how to do it, send me an email at celsolivero.no.gmail.com