Recherche de fichiers avec Picturebox et GIf animé qui s'anime pas.

Signaler
Messages postés
3276
Date d'inscription
lundi 11 novembre 2013
Statut
Membre
Dernière intervention
18 juillet 2021
-
Messages postés
2440
Date d'inscription
samedi 11 janvier 2014
Statut
Contributeur
Dernière intervention
18 juillet 2021
-
Bonjour / Bonsoir.

Auparavant, je m'étais fait un script qui faisait de la recherche recursive.


J'ai voulu faire pareil, mais avec un petit picturebox avec Gif Animé.


Le script en lui-même, pas de souci.

Cependant, comme je le présentais : le gif animé, ne l'est pas.
Je pense que cela est normal.

Du coup, j'essaye d'apprendre et de comprendre les Threads.
Et j'ai du mal avec ce concept.


Pouvez-vous m'en dire plus ?


Voici le code en question (WinForm, c# et framework, via Visual Community 2019) :

using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace RechRecursive
{
    public partial class Form1 : Form
    {
        int count = 0;

        public Form1()
        {
            InitializeComponent();
        }


        private void button1_Click(object sender, EventArgs e)
        {
            var dlg = new FolderBrowserDialog();
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                string path = dlg.SelectedPath;
                textBox1.Text = path;
            }

        }

        private void button2_Click(object sender, EventArgs e)
        {
            /* code qui ne fonctionne pas - le gif est animé

            listView1.Items.Clear();
            string ds = textBox1.Text;
            string term = "*" + textBox2.Text + "*";

            pictureBox1.Show();

            await Task.Run(() => Recherche(ds, term));

            pictureBox1.Hide();
            */


            /* code qui fonctionne - mais pas de gif animé (il est fixe)  */

            listView1.Items.Clear();
            string ds = textBox1.Text;
            string term = "*" + textBox2.Text + "*";

            pictureBox1.Show();
            pictureBox1.Refresh();

            Recherche(ds, term);


            pictureBox1.Hide();
           

        }

        



        private void Recherche(string ds, string term)
        {
            try
            {
                string[] fichiers = Directory.GetFiles(ds, term);
                foreach (string fichier in fichiers)
                {
                    count++;
                    ListViewItem itm = listView1.Items.Add(count.ToString());
                    itm.SubItems.Add(fichier);
                }
            }
            catch { }
            
            try
            {
                string[] dossiers = Directory.GetDirectories(ds);
                foreach (string dossier in dossiers)
                {
                    Recherche(dossier, term);
                }
            }
            catch { }
        
        }

    }
}




En gros, la recherche prend le dessus, par rapport au picturebox.
J'ai donc pensé au thread, chose que je n'ai jamais faite.


J'aimerai donc m'y attelé.

Comprendre le concept, et ainsi l'appliquer.


Merci en tout cas de l'aide, que vous pourrez m'apporter.



++ ;)

9 réponses

Messages postés
2440
Date d'inscription
samedi 11 janvier 2014
Statut
Contributeur
Dernière intervention
18 juillet 2021
138
Bonjour
Il faut utiliser un BackGroundWorker pour faire la recherche récursive . Attention au fait que le BackGroundworker fonctionne dans un Thread à part et ne peut pas accéder aux contrôles de la Form principale .
Donc la Listview ne sera remplie qu'à la fin de la recherche récursive .
Les exemples ne manquent pas sur le NET


Messages postés
3276
Date d'inscription
lundi 11 novembre 2013
Statut
Membre
Dernière intervention
18 juillet 2021

Salut.

Tu me parles chinois pour l'instant, XD

En tout cas, merci de ta réponse.


Je vais voir ce que je peux faire.

J'ai essayé : pour l'instant, ça foire. ^^


++
Messages postés
2440
Date d'inscription
samedi 11 janvier 2014
Statut
Contributeur
Dernière intervention
18 juillet 2021
138
Bonsoir
Je te parles en bon français .
As-tu regardé sur le NET ce qu'est un BackGroundWorker ? As-tu regardé comment on l'utilise ?
regarde ici : https://webman.developpez.com/articles/dotnet/introbackroundworker/
Messages postés
3276
Date d'inscription
lundi 11 novembre 2013
Statut
Membre
Dernière intervention
18 juillet 2021

Je n'ai pas dit le contraire.

je dis juste que pour moi, c'est l'inconnu.

Et oui, je fais que regarder, je teste, et ça foire.
Messages postés
3276
Date d'inscription
lundi 11 novembre 2013
Statut
Membre
Dernière intervention
18 juillet 2021

Re.

Je dois merder quelque part, mais je persévère.

En tout cas, ce que j'ai pour l'instant, c'est "l'inverse"
- La recherche se fait
- Le gif s'anime à la fin

Je verrais ça plus tard, je baisse pas les bras.

Merci de ton intervention ;)


Bonne soirée à toi.
Messages postés
2440
Date d'inscription
samedi 11 janvier 2014
Statut
Contributeur
Dernière intervention
18 juillet 2021
138
Si tu postais le code complet de ta Form je pourrais te dire ce qui ne va pas !
Messages postés
3276
Date d'inscription
lundi 11 novembre 2013
Statut
Membre
Dernière intervention
18 juillet 2021

Lu

Bon, je débute dans tout ce qui est backgrounder et cie.

J'ai toujours du mal au début, mais quand je comprends le principe, mieux c'est ^^

Voici le code

using System;
using System.ComponentModel;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace RechRecursive
{
    public partial class Form1 : Form
    {

        int count = 0;

        public Form1()
        {
            InitializeComponent();
            //BackgroundWorker bgw1 = new BackgroundWorker();

            backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
            backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
            backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);

            pictureBox1.Visible = false;

        }


        private void button1_Click(object sender, EventArgs e)
        {
            var dlg = new FolderBrowserDialog();
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                string path = dlg.SelectedPath;
                textBox1.Text = path;
            }

        }

        private void button2_Click(object sender, EventArgs e)
        {
            //pictureBox1.Visible = true;
            //backgroundWorker1.RunWorkerAsync();
            backgroundWorker1.RunWorkerAsync(pictureBox1.Visible=true);
            ExecRecherche();


        }



        private void ExecRecherche()

        {
            //DisplayPleaseWait();
            string ds = textBox1.Text;
            string term = "*" + textBox2.Text + "*";
            Recherche(ds, term);
        }

        private void Recherche(string ds, string term)
        {
            try
            {
                string[] fichiers = Directory.GetFiles(ds, term);
                foreach (string fichier in fichiers)
                {
                    count++;
                    ListViewItem itm = listView1.Items.Add(count.ToString());
                    itm.SubItems.Add(fichier);
                }
            }
            catch { }

            try
            {
                string[] dossiers = Directory.GetDirectories(ds);
                foreach (string dossier in dossiers)
                {
                    Recherche(dossier, term);
                }
            }
            catch { }

        }


        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            ExecRecherche();
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
        
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {

        }

    }



}



Bon, comme tu vois, ce n'est pas ça.


Et je pense, si je ne me trompe pas, que c'est par rapport à ton conseil du début :
« Attention au fait que le BackGroundworker fonctionne dans un Thread à part et ne peut pas accéder aux contrôles de la Form principale . »


Du coup, j'essaye aussi de comprendre le fonctionnement des Threads.


Merci ;)
Bonne soirée.
Messages postés
2440
Date d'inscription
samedi 11 janvier 2014
Statut
Contributeur
Dernière intervention
18 juillet 2021
138
Bonjour
Voici le code complet d'une Form avec
- 1 Label pour le répertoire sélectionné
- 2 Boutons : un pour sélectionner le répertoire et un pour afficher la liste des fichiers
- 1 Textbox où on place un filtre pour les fichiers
- 1 BackGrounWorker pour le Thread en tache de fond
- 1 Listview en mode Details pour afficher les fichiers avec une colonne contenant le nom complet du fichier
- 1 Picturebox pour afficher le Gif animé

J'ai pas testé avec un gif animé
J'ai pas testé le filtre ( si textbox2 est vide on prend tous les fichiers )

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        private List<string> ListFichiers;
        
        public Form1()
        {
            InitializeComponent();
        }

        /// <summary>
        /// chargement de la form
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            listView1.Items.Clear();
            pictureBox1.Visible = false;
        }

        /// <summary>
        /// Sélection d'un répertoire
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button1_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog dlg = new FolderBrowserDialog();
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                string Path = dlg.SelectedPath;
                label1.Text = Path;
            }
        }

        /// <summary>
        /// Liste des fichiers
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button2_Click(object sender, EventArgs e)
        {
            pictureBox1.Visible = true;
            pictureBox1.Show(); // le gif animé
            Cursor = Cursors.WaitCursor; // curseur en attente
            backgroundWorker1.RunWorkerAsync(); // on demarre la recherche en BackGround 
        }

        /// <summary>
        /// REcherche des fichiers en BackGround
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BackgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
        {
            string ds = label1.Text; // dossier de recherche
            // si le filtre est vide on recherche tous les fichiers
            string term = textBox2.Text == string.Empty ? "*.*" : "*" + textBox2.Text + "*";
            ListFichiers = new List<string>();
            Recherche(ds, term);
        }

        /// <summary>
        /// Recherche des fichiers avec récusivité 
        /// </summary>
        /// <param name="ds"></param>
        /// <param name="term"></param>
        private void Recherche(string ds, string term)
        {
            try
            {
                string[] fichiers = Directory.GetFiles(ds, term);
                foreach (string fichier in fichiers)
                {
                    ListFichiers.Add(fichier);
                }
            }
            catch { }
            try
            {
                string[] dossiers = Directory.GetDirectories(ds);
                foreach (string dossier in dossiers)
                {
                    Recherche(dossier, term);
                }
            }
            catch { }
            }
        }

        /// <summary>
        /// fin du BackGround et affichage des fichiers
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BackgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Cursor = Cursors.Default;
            pictureBox1.Visible = false; // on arrête le Gif animé 
            listView1.BeginUpdate();
            // on affiche les fichiers dans la listview
            for (int i = 0; i <= ListFichiers.Count - 1; i++)
                listView1.Items.Add(new ListViewItem(new string[] { ListFichiers[i] }));
            listView1.EndUpdate();
        }
    }
}


en prime une vue de ma Form

Messages postés
16102
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
19 juillet 2021
554
Bonsoir

C'est la recherche qu'il faut lancer dans le backgroundworker.
Le fait de rendre visible le picturebox doit être fait par le thread principal (y'a des moyens de faire dans le backgroundworker mais dans ton cas ça n'a pas d'intêret).

Or ton code, fait exactement l'inverse

        private void button2_Click(object sender, EventArgs e)
        {
            //pictureBox1.Visible = true;
            //backgroundWorker1.RunWorkerAsync();
            backgroundWorker1.RunWorkerAsync(pictureBox1.Visible=true);
            ExecRecherche();


        }


En fait les 2 lignes en commentaires sont celles qui devraient être là.

Ensuite ta recherche ne doit pas remplir une listView, pour 2 raisons:
  • le fait qu'un thread ne peux pas accéder directement aux controles.
  • et surtout le fait que C# ne se code pas comme ça (enfin si on veut bien coder)


Ta recherche doit remplir une List<string> dont la portée s'étend à tout le formulaire (pour l'exemple, je l'appelle resultats)

Une fois fini, l'événement WorkCompleted va se déclencher. Dans la méthode que tu y a abonné, tu vas affecter l'affichage de la liste de résultats dans la listview
        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
               int count = 0;
               foreach(string fichier in resultats)
                {
                    count++;
                    ListViewItem itm = listView1.Items.Add(count.ToString());
                    itm.SubItems.Add(fichier);
                }
        }




Messages postés
2440
Date d'inscription
samedi 11 janvier 2014
Statut
Contributeur
Dernière intervention
18 juillet 2021
138
bonjour Whis
Je pense qu'avec nos 2 interventions il devrait s'en sortir .
J'espère que tout va bien chez toi .
A ++
Messages postés
16102
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
19 juillet 2021
554
J'avais pas rafraichi la page avant de valider mon ;)

Ça va bien et toi?
Messages postés
2440
Date d'inscription
samedi 11 janvier 2014
Statut
Contributeur
Dernière intervention
18 juillet 2021
138
Chez nous tout va bien merci !
A ++