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

little boy62 Messages postés 3403 Date d'inscription lundi 11 novembre 2013 Statut Membre Dernière intervention 2 octobre 2022 - 14 juil. 2021 à 19:18
vb95 Messages postés 3079 Date d'inscription samedi 11 janvier 2014 Statut Non membre Dernière intervention 3 octobre 2022 - 18 juil. 2021 à 22:24
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

vb95 Messages postés 3079 Date d'inscription samedi 11 janvier 2014 Statut Non membre Dernière intervention 3 octobre 2022 158
16 juil. 2021 à 11:59
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


0
little boy62 Messages postés 3403 Date d'inscription lundi 11 novembre 2013 Statut Membre Dernière intervention 2 octobre 2022
Modifié le 17 juil. 2021 à 23:03
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. ^^


++
0
vb95 Messages postés 3079 Date d'inscription samedi 11 janvier 2014 Statut Non membre Dernière intervention 3 octobre 2022 158
17 juil. 2021 à 23:13
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/
0
little boy62 Messages postés 3403 Date d'inscription lundi 11 novembre 2013 Statut Membre Dernière intervention 2 octobre 2022
17 juil. 2021 à 23:19
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.
0
little boy62 Messages postés 3403 Date d'inscription lundi 11 novembre 2013 Statut Membre Dernière intervention 2 octobre 2022
17 juil. 2021 à 23:35
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.
0
vb95 Messages postés 3079 Date d'inscription samedi 11 janvier 2014 Statut Non membre Dernière intervention 3 octobre 2022 158
17 juil. 2021 à 23:37
Si tu postais le code complet de ta Form je pourrais te dire ce qui ne va pas !
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
little boy62 Messages postés 3403 Date d'inscription lundi 11 novembre 2013 Statut Membre Dernière intervention 2 octobre 2022
18 juil. 2021 à 19:42
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.
0
vb95 Messages postés 3079 Date d'inscription samedi 11 janvier 2014 Statut Non membre Dernière intervention 3 octobre 2022 158
Modifié le 18 juil. 2021 à 22:02
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

0
Whismeril Messages postés 17820 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 3 octobre 2022 618
18 juil. 2021 à 22:12
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);
                }
        }




0
vb95 Messages postés 3079 Date d'inscription samedi 11 janvier 2014 Statut Non membre Dernière intervention 3 octobre 2022 158
18 juil. 2021 à 22:18
bonjour Whis
Je pense qu'avec nos 2 interventions il devrait s'en sortir .
J'espère que tout va bien chez toi .
A ++
0
Whismeril Messages postés 17820 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 3 octobre 2022 618
18 juil. 2021 à 22:20
J'avais pas rafraichi la page avant de valider mon ;)

Ça va bien et toi?
0
vb95 Messages postés 3079 Date d'inscription samedi 11 janvier 2014 Statut Non membre Dernière intervention 3 octobre 2022 158
18 juil. 2021 à 22:24
Chez nous tout va bien merci !
A ++
0