Call Form2 with Circular Progress Bar while another action is executed C #

0

I am having a question about calling a Windows Form. In this application, through the click event of the button located on Form1, call a second Form, where on this form2 I present an animated Progress Bar Circular running until another method located on Form 1 called LoadGrid () is terminated.

At this point my application has the following code:

Button event located on Form 1:

publicpartialclassfrm_Painel_de_Producao:Form{frm_Progress_Barpb=frm_Progress_Bar();privateasyncvoidbtnAtualizaGrid_Click(objectsender,EventArgse){pb.Show();//desabilitaosbotõesenquantoatarefaéexecutada.btnCancelar.Enabled=false;btnIncluir.Enabled=false;btnAtualizaGrid.Enabled=false;//simplystartandawaittheloadingtaskawaitTask.Run(()=>carregarGrid());pb.Close();//habilitaosbotõesapóstarefaeventodeloading.btnAtualizaGrid.Enabled=true;btnCancelar.Enabled=true;btnIncluir.Enabled=true;}}

Form2codeonlyInitialize:

publicpartialclassfrm_Progress_Bar:Form{publicfrm_Progress_Bar(){InitializeComponent();}}

Form2Designer+ProgressBar:

Form2Property:BackColor=FuchsiaTransparencyKey=Fuchsia

CircularProgressBarproperty:

InthiscaseinthepropertiesalreadyhaveStyle:MarqueeForIreadsomewherethatthispropertyshouldbelikeMarquee,"if I am not mistaken in order to continue giving the loading effect." / p>

Form 1 Method LoadGrid:

public void carregarGrid()
    {

        timer.Interval = 1000;
        timer.Tick += meuRelogio;
        timer.Start();
        dgvProducao.AutoGenerateColumns = false;
        dgvProducao.DataSource = clsPPCP.painelProducao();
        MeuBD.AbreXML();
        if (MeuBD.RequerUsuario == "1")
        {
            txtOperador.Focus();
        }
        else
        {
            txtOperador.Hide();
            txtNomeOperador.Hide();
            label8.Hide();
            txtCartao.Focus();
        }
        colorirGrid();
        //MeuBDex.AbreXML();
        relogio();   
    }

With this information I now report the errors I found:

This error is happening because in the click event I am putting the following code: await Task.Run(() => carregarGrid());

This causes the legendary error: Invalid thread operation: control '' accessed from a thread that is not the one in which it was created.

I tried to redo this application then using Thread and Delegates but I also did not succeed for lack of experience with Threads.

And once again I've refactored this application trying to point to the Load event of Form2, call the LoadGrid method of Form1. Respecting the instance creation of Form 1 within Form2. But I was not successful either.

So I humbly ask you guys how I can solve this application? Questions:

1- What is the best way to work with Circular Progress Bar?

2- Use ProgressBar in another Form as in the example above? Or I can put the Progress Bar on the same Form1.

3- It would also be possible in the Load event of Form 1 to be calling the LoadGrid method and once the method is finished, the ProgressBar with Form2 is terminated?

I leave my thanks for all the help. Thank you!

    
asked by anonymous 18.06.2018 / 17:14

1 answer

1

There are several ways to make the progress bar, but I believe that if it is Windows Forms , ideally use the BackgroundWorker that performs background work, leaving the form's Thread free to show progress in bar.

I've done an example of how it works:

private void button1_Click(object sender, EventArgs e)
{
    if (!backgroundWorker1.IsBusy) //se o bw não estiver ocupado...
    {
        int arg = 100000;
        backgroundWorker1.RunWorkerAsync(arg); //você pode passar um argumento pro bw
    }
}


private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    //iniciou o processo em segundo plano
    int total = (int)e.Argument;
    int valor = 0;
    for (int i = 0; i <= total; i++)
    {
        valor += i;

        int p = i * 100 / total; //calcula percentual do progresso

        backgroundWorker1.ReportProgress(p); //informa o percentual do progresso
    }

    e.Result = valor;
}

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar1.Value = e.ProgressPercentage; //exibe o percentual na barra
}

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    //evento quando o processo é finalizado
    if (e.Cancelled)
    {
        //processo foi cancelado
        //tem que definir o bw pra suportar cancelamento e verificar a flag e.Cancel dentro do processo...
    }
    else if (e.Error != null)
    {
        //deu erro e foi lançada exceção
    }
    else
    {
        int resultado = (int)e.Result;
        MessageBox.Show("Resultado: "+ resultado);
    }
}
  

The example above answers questions 1 and 2. A 3, just fire bw after you open the form. Closing the other form with progressBar is no longer necessary ...

To insert BackGroundWorker simply drag it from the toolbar:

Andthenputtheevents:

    
18.06.2018 / 17:44