ProgressBar on search button

2019-02-25 02:37发布

I have this c# code to show a progressbar:

{
    public partial class FormPesquisaFotos : Form
    {
        public FormPesquisaFotos()
        {
            InitializeComponent();
        }

        private void FormPesquisaFotos_Load(object sender, EventArgs e)
        {
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //Mostra a barra de progresso da pesquisa
            while (progressBar1.Value < 100)
            progressBar1.Value += 1;
            {
                //Criar um objeto (instância, cópia) da classe FormResultadosFotos
                FormResultadosFotos NovoForm = new FormResultadosFotos();
                NovoForm.Show();
            }
        }
    }
}

It only loads at the end of the search (after button click). How can I have progressbar running at the beginning of the search?

Here is the code to show the results on a new form. Progressbar stops at 95% and after a few seconds it shows the results.

{
    public partial class FormResultadosFotos : Form
    {
        public FormResultadosFotos()
        {
            InitializeComponent();
        }
        private void FormFotos_Load(object sender, EventArgs e)
        {
            // se pretendermos pesquisar em várias pastas
            List<string> diretorios = new List<string>()
            {@"\\Server\folder01\folder02"};

            // se pretendermos pesquisar as várias extensões
            List<string> extensoes = new List<string>()
    {".jpg",".bmp",".png",".tiff",".gif"};

            DataTable table = new DataTable();
            table.Columns.Add("Nome e formato do ficheiro (duplo clique para visualizar a imagem)");
            table.Columns.Add("Caminho ( pode ser copiado Ctrl+C )");
            foreach (string diretorio in diretorios)
            {
                var ficheiros = Directory.EnumerateFiles(diretorio, "*", SearchOption.AllDirectories).
                    Where(r => extensoes.Contains(Path.GetExtension(r.ToLower())));
                foreach (var ficheiro in ficheiros)
                {
                    DataRow row = table.NewRow();
                    row[0] = Path.GetFileName(ficheiro);
                    row[1] = ficheiro;
                    table.Rows.Add(row);
                }
            }
            dataGridView1.DataSource = table;
            dataGridView1.Columns[1].Visible = true;
        }
        private void dataGridView1_DoubleClick(object sender, EventArgs e)
        {
            FormPictureBox myForm = new FormPictureBox();
            string imageName = dataGridView1.CurrentRow.Cells[1].Value.ToString();
            Image img;
            img = Image.FromFile(imageName);
            myForm.pictureBox1.Image = img;
            myForm.ShowDialog();
        }
    }
}

Thank you.

2条回答
叼着烟拽天下
2楼-- · 2019-02-25 03:24

You must have it on a new thread and not on the main thread.

Here is a little example:

private void buttonWorkerTest_Click(object sender, RoutedEventArgs e)
{
    this.progressBarWorkerTest.Value = 0;
    BackgroundWorker worker = new BackgroundWorker();
    // Event for the method that will run on the background
    worker.DoWork += this.Worker_DoWork;
    // Event that will run after the BackgroundWorker finnish
    worker.RunWorkerCompleted += this.Worker_RunWorkerCompleted;
    worker.RunWorkerAsync();


}

private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
    for (int i = 1; i <= 100; i++)
    {
        Dispatcher.Invoke(new Action(() =>
        {
            this.progressBarWorkerTest.Value = i;
        }));
        Thread.Sleep(100);
    }
}

private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    // You can put the code here to open the new form and such
}

The Dispacher.Invoke is because its on WPF, for WinForm just change it to this.Invoke

This example, is when the button is clicked the BackgroundWorker it will start, there is a for to go from 1 to 100 and it will sleep 100 miliseconds and will update the progressbar.

Hope that this it will help out

Edit

Did include now on the example the event to run when the BackgroundWorker finnish, just in case if there is the need for it

Edit 2:

My advice is when searching for the photos on the background insert them into a DataTable all rdy, since your all ready searching for them and the work can be done here also, then just make a constructor on the FormResultadosFotos that will receive that DataTable.

From what I did understood the main goal to was to search them on the form FormPesquisaFotos (thats why we have the background worker there, to search for them and update the ProgressBar) and show them on the new form AKA FormResultadosFotos

// Lets create a DataTable variable to be access on the Worker_DoWork and then on the Worker_RunWorkerCompleted
private DataTable tableOfPhotos;

private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
    // Search for the photos here and then add them to the DataTable
    this.tableOfPhotos = new DataTable();
    tableOfPhotos.Columns.Add("Nome e formato do ficheiro (duplo clique para visualizar a imagem)");
    tableOfPhotos.Columns.Add("Caminho ( pode ser copiado Ctrl+C )");
    foreach (string diretorio in diretorios)
    {
        // se pretendermos pesquisar em várias pastas
        List<string> diretorios = new List<string>()
        {@"\\Server\folder01\folder02"};

        // se pretendermos pesquisar as várias extensões
        List<string> extensoes = new List<string>()
        {"*.jpg","*.bmp","*.png","*.tiff","*.gif"};

        var ficheiros = Directory.EnumerateFiles(diretorio, "*", SearchOption.AllDirectories).
            Where(r => extensoes.Contains(Path.GetExtension(r.ToLower())));
        foreach (var ficheiro in ficheiros)
        {
            DataRow row = tableOfPhotos.NewRow();
            row[0] = Path.GetFileName(ficheiro);
            row[1] = ficheiro;
            tableOfPhotos.Rows.Add(row);
        }
    }
}

private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    // You can put the code here to open the new form and such
    FormResultadosFotos NovoForm = new FormResultadosFotos(this.tableOfPhotos);
    NovoForm.Show();
}


// Constructor that will receive the DataTable and put it into the dataGridView1, it should be added on the Form FormResultadosFotos
Public FormResultadosFotos(DataTable table)
{
    InitializeComponent();
    // In here we will tell the where is the source for the dataGridView1
    this.dataGridView1.DataSource = table;
}

In here you could all also to see what the table bring's by puting a breakpoint on the line this.dataGridView1.DataSource = table;, if the table is empty there was nothing introduced into the table (maybe no photos on the directory ? Can't access to it? Not at work and don't have any IDE with me, just basing my anwser from what I have in my head, but you could also get the files on a simular code if needed:

List<string> tempList = new List<string>;
foreach (string entryExt in extensoes)
{
    foreach (string entryDir in diretorios)
    {
        //  SearchOption.AllDirectories search the directory and sub directorys if necessary
        // SearchOption.TopDirectoryOnly search only the directory
        tempList.AddRange(Directory.GetFiles(entryDir, entryExt, SearchOption.AllDirectories));
    }
}

// Here would run all the files that it has found and add them into the DataTable
foreach (string entry in tempList)
{
    DataRow row = tableOfPhotos.NewRow();
    row[0] = Path.GetFileName(entry);
    row[1] = entry;
    tableOfPhotos.Rows.Add(row);
}

Edit 3:

Change on your code the

List<string> extensoes = new List<string>(){".jpg",".bmp",".png",".tiff",".gif"};

to

List<string> extensoes = new List<string>(){"*.jpg","*.bmp","*.png","*.tiff","*.gif"};

You need the * before the extension (.png as example) to search files for that extension

查看更多
3楼-- · 2019-02-25 03:38

What you're describing here is a multi threading issue. Your loop runs before the UI has a chance to update itself.

You should check out https://stephenhaunts.com/2014/10/14/using-async-and-await-to-update-the-ui-thread/ for an explanation & an example on how to update the UI while you're in a loop.

Regards

查看更多
登录 后发表回答