none
Charger des images d'un dossier local dans une listeview avec une progressbar sans bloquer l'interface RRS feed

  • Question

  • Bonjour,

    Je cherche un moyen de charger des images depuis un emplacement local dans une listeview avec un backgroundworker et une progressbar en cliquant sur un bouton.

    J'arrive a charger les images, mais lors du chargement, l'application se bloque, et la progressbar ne fonctionne pas.

    Pouvez-vous m'aider svp. D'avance Merci.

    voici mon code :

    public string RootPathPhotos = (@"D:\Mes Photos\").ToString(); public USER_Photos() { InitializeComponent(); backgroundWorker1 = new BackgroundWorker(); backgroundWorker1.WorkerReportsProgress = true; backgroundWorker1.WorkerSupportsCancellation = true; backgroundWorker1.DoWork += BackgroundWorker1_DoWork; backgroundWorker1.ProgressChanged += BackgroundWorker1_ProgressChanged; backgroundWorker1.RunWorkerCompleted += BackgroundWorker1_RunWorkerCompleted; } public void ScanDirectory(string directory, string searchPattern) { try { foreach (var file in Directory.GetFiles(directory)) { if (backgroundWorker1.CancellationPending) { return; } lblProgress.Invoke((Action)(() => lblProgress.Text = file)); if (file.Contains(searchPattern)) { AddToListView(file); } } foreach (var dir in Directory.GetDirectories(directory)) { ScanDirectory(dir, searchPattern); } } catch { } } public void AddToListView(string image) { FileInfo finfo = new FileInfo(image); LV_AlbPho.Invoke((Action)(() => { LV_AlbPho.BeginUpdate(); LV_AlbPho.Clear(); LV_AlbPho.View = View.LargeIcon; imageList_Folder.ImageSize = new Size(240, 240); imageList_Folder.ColorDepth = ColorDepth.Depth16Bit; imageList_Folder.Images.Add(Image.FromFile(image)); for (int _index = 0; _index < imageList_Folder.Images.Count; _index++) { var item = new ListViewItem(); item.ImageIndex = _index; LV_AlbPho.Items.Add(item); } LV_AlbPho.LargeImageList = imageList_Folder; backgroundWorker1.ReportProgress(100); LV_AlbPho.EndUpdate(); })); } private void BackgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { string[] dirs = Directory.GetDirectories(RootPathPhotos); float length = dirs.Length; progressBar1.Invoke((Action)(() => progressBar1.Maximum = dirs.Length)); ScanDirectory(RootPathPhotos, txtSearch.Text); for (int i = 0; i < dirs.Length; i++) { backgroundWorker1.ReportProgress((int)(i / length * 100)); ScanDirectory(dirs[i], txtSearch.Text); } backgroundWorker1.ReportProgress(100); } private void BackgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { if (!backgroundWorker1.CancellationPending) { lblPercent.Text = e.ProgressPercentage + "%"; progressBar1.PerformStep(); } } private void BackgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (progressBar1.Value < progressBar1.Maximum) { lblProgress.Text = "ok" + lblProgress.Text; } }

    private void BTN_ListeImages_Click(object sender, EventArgs e)
            {
                    LV_AlbPho.Items.Clear();
                    imageList_Folder.Images.Clear();
                    backgroundWorker1.RunWorkerAsync();
                }
            }





    samedi 26 septembre 2020 14:16

Réponses

  • Salut, le post date de un mois facile mais bon tu seras peut être toujours intéressé par ces infos

    je tiens a signaler que je ne suis pas un professionnel.

    Donc pour résumer tes questions pour le blocage de l'app c'est du a un bout de code mis au mauvais endroit dans la méthode AddToListView:

    imageList_Folder.Images.Add(Image.FromFile(image));

    en fait il faut créer l'image en dehors du Invoke et la stocker dans un objet Image et passé l'objet en paramètre

    en dehors du Invoke:

    Image img=Image.FromFile(image);

    et ensuite dans le Invoke

    imageList_Folder.Images.Add(Image.FromFile(img));

    Pour la methode BackgroundWorker_DoWork()

    il y a deux fois la méthode ScanDirectory, bizarre, peut être que tu testais différentes solution

    celle qui se trouve dans la boucle ne s'exécutera jamais si il n'y a pas de sous dossier dans le path sélectionné,vu que tu utilises GetDirectory.Length pour la boucle, du coup la progressbar ne fonctionnera pas

    et pour finir il y a d'autre petites erreurs,mais qui n' en fait pas, on apprends de ces erreurs

    Du coup j' ai pris ton code et je t’ai mis des commentaires sur les changement minimum effectuées, tu pourras ensuite virer le code commenté inutile

    Il y a bien sur pas mal de chose a coder comme par exemple empêcher de cliquer sur le bouton avant que la tache soit fini,sinon erreur.

    Voila, j'espère que ça t'aidera.

    De mon coté du coup j'ai passé le weekend à faire évoluer ton bout de code et c'est pas terminé,merci pour l'idée j'avais jamais utilisé le ListView qui d'ailleur est bien relou au niveau de son fonctionnement. Si tu souhaites voir ce que j'ai codé de mon coté dis le moi je l'ai dépot sur GIT, je sais pas trop comment on donne accès a quelqu'un mais on verra ça, suis tout nouveau sur git,et tout in english, @++ peut être

    Voici ton code commenté: il y a des using a ajouter, de tout façcon visual te l'indiquera

    using System.Reflection; using System.Threading.Tasks; public USER_Photos() { InitializeComponent(); backgroundWorker1.WorkerReportsProgress = true; backgroundWorker1.WorkerSupportsCancellation = true; backgroundWorker1.DoWork += BackgroundWorker1_DoWork; backgroundWorker1.ProgressChanged += BackgroundWorker1_ProgressChanged; backgroundWorker1.RunWorkerCompleted += BackgroundWorker1_RunWorkerCompleted; //Code enlevé de methode bouton_Click,comme ça on a une initialisation et //configuration par défaut de ListView et ImageList,sachant que si vous souhaitez //utiliser la vue SmallIcon,List,ou détails du ListView, il faudra avoir un 2eme composant //ImageList deppuis le designer,ou declarer une nouvelle instance de ImageList dans le code LV_AlbPho.View = View.LargeIcon; imageList_Folder.ImageSize = new Size(240, 240); imageList_Folder.ColorDepth = ColorDepth.Depth32Bit; LV_AlbPho.LargeImageList = imageList_Folder; LV_AlbPho.SmallImageList = imageList_Folder; LV_AlbPho.ArrangeIcons(ListViewAlignment.SnapToGrid); LV_AlbPho.AutoArrange = true; //Ativation du DoubleBuffer pour réduire les scintillements lor du remplissage du tableau //en utilisant une méthode d'extension qui se trouve tout en bas du code dans une class à part LV_AlbPho.DoubleBuffered(true); } BackgroundWorker backgroundWorker1=new BackgroundWorker();

    //La si tu avais utilisé un composant ImageList depuis la boite à outil en mode design

    // tu n'as pas a mettre cette ligne la qui instancie un objet ImageList ImageList imageList_Folder = new ImageList(); //variable ajouté int incr = -1; //valeur d'incrément utilisé dans AddToListView() pour les items int incrPrgBar=0; //valeur d'incrément pour la progressbar // ici faut remettre un path valide bien sûr := public string RootPathPhotos = (@"Pictures").ToString(); public void ScanDirectory(string directory, string searchPattern) { //total fichier du repértoire float nbtfile = Directory.GetFiles(directory).Length; int pct = 0;//pourcentage try { foreach (var file in Directory.GetFiles(directory)) { ///////////////////code de progression /////////////////// //exécuté avant traitement fichier au cas ou un catch exécuté incrPrgBar += 1; if (backgroundWorker1.CancellationPending) { return; } pct = (int)(incrPrgBar / nbtfile * 100); lblProgress.Invoke((Action)(() => lblProgress.Text = file)); backgroundWorker1.ReportProgress(pct); // ca c'est pour le rafraichissement net de la progressbar quand le scan // est rapide car la pattern ne match pas,donc exécution de la boucle code rapide //peut etre mis en commentaire System.Threading.Thread.Sleep(2); //////////////////////////////////////////////// if (file.Contains(searchPattern)) { try { AddToListView(file); } catch (Exception) { //si file n'est pas une image,corrompu,ou pas pris en charge par le ListView on poursuit continue; } } } foreach (var dir in Directory.GetDirectories(directory)) { incrPrgBar = 0;//scan nouveau repertoire =compteur à zéro de progressbar try { ScanDirectory(dir, searchPattern); } catch (Exception) { //si file n'est pas une image,corrompu,ou pas pris en charge par le ListView on poursuit continue; } } } catch (Exception x) { MessageBox.Show(x.Message); } } public void AddToListView(String image) { //pour le texte affiché pour l'image string finfo = new FileInfo(image).Name; //On créer l'image bitmap en dehors du Invoke, Sionon c'est ça qui bloque l'app Image img = Image.FromFile(image); LV_AlbPho.Invoke((Action)(() => { //peut être désactivé //LV_AlbPho.BeginUpdate(); //cette ligne efface tout les éleméments, c' eest pas ce qu'on veut //LV_AlbPho.Clear(); //La ligne de code qui suit ce commentaire ne doit pas être ici: //Propiété View détermine dans quel mode le ListView va afficher les images //donc on doit définir ou changer sa propriété avant de remplir le ListView //cette propriété utilise soit l'objet LargeImageList quand View=View.LargeIcon //soit SmallImageList dans les modes View.SmallIcon , View.Détail, View.List //cependant,si on souhataite passer de LargeIcon à SmallIcon à tout moment,c'est possible

    //avec un bouton ou menu,et on placera ce code dans la méthode on_Click

    //LV_AlbPho.View = View.LargeIcon; //les 2 lignes suivante sont des propiétés qui n'ont pas à être redéfini pour chaque image //affectée a l'objet ImageList, se sont les propiétés de l'objet ImageList,dailleur elles //ne doivent pas changer pour remplir l'objet d'image //imageList_Folder.ImageSize = new Size(240, 240); //imageList_Folder.ColorDepth = ColorDepth.Depth16Bit; imageList_Folder.Images.Add(img); LV_AlbPho.Items.Add(finfo, incr += 1); //La boucle remplacé par la ligne du dessus,car inutile de réaffecter tout les valeurs //for (int _index = 0; _index < imageList_Folder.Images.Count; _index++) //{ // var item = new ListViewItem(); // item.ImageIndex = _index; // LV_AlbPho.Items.Add(item); //} //la ligne de code qui suit ce commentaire ne doit pas être ici: //La propiété LargeImageList utilise l'objet imageList_Folder qui contient les images //il doit donc être défini avant toute exécution de code dont la tache sera de remplir le //l'objet ImageList,c'est pourquoi on affectera l'objet à cette propiété en dehors des //méthodes de remplissage de l'objet,par exemple dans le public Form1() si vous avez //implémenté l'objet ImageList vous même,ou si vous avez utilisé la boite à outil pour //déposer un composant ImageList,alors à partir du panneau des propiétés du composant //ListView,affectez la propiété LargeImageList avec le composant ImageList. //Note: Le fait de remplir l'objet ImageList va rafrichir le ListView au fur et a mesure //LV_AlbPho.LargeImageList = imageList_Folder; // //la ligne de code qui suit ce commentaire ne fait pas ce qui est souhaitez, //étant donné que vous avez définicomme maximum de votre progressbar le nombre //de repertoires trouvés,hors la méthode dans laquelle nous sommes est appelée //pour chaque image trouvé //backgroundWorker1.ReportProgress(100); //peut être désactivé //LV_AlbPho.EndUpdate(); })); } private void BackgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { string[] dirs = Directory.GetDirectories(RootPathPhotos); //Plus nécessaire ProgressBar est géré dans la méthode ScanDirectory //float length = (dirs.Length == 0) ? 1 : dirs.Length; //progressBar1.Invoke((Action)(() => progressBar1.Maximum = (int)length)); //Ptete qui faudrait un try la mais bon y en a déja dans la méthode ScanDirectory(RootPathPhotos, txtSearch.Text); //cette boucle non plus, n'est plus nécessaire //for (int i = 0; i <= dirs.Length; i++) //{ // backgroundWorker1.ReportProgress((int)(i / length * 100)); // ScanDirectory(dirs[i], txtSearch.Text); //} backgroundWorker1.ReportProgress(100); } private void BackgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { if (!backgroundWorker1.CancellationPending) { //ici on récupère le pourcentage lblPercent.Text = e.ProgressPercentage + "%"; progressBar1.Value= e.ProgressPercentage; } } private void BackgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { //La comprend pas le raisonnement enfin si mais alors c'est un = et pas < a mon avis // //if (progressBar1.Value < progressBar1.Maximum) //{ // lblProgress.Text = "ok" + lblProgress.Text; //} //vu que cette méthode est déclenché par évenement tache terminé ou annulé le mieux a mon avis //c'est de gérer les évenements et au pire initialiser ce qui doit l'être if (e.Cancelled) { lblProgress.Text = "recherche arrêtée"; } else if (e.Error != null) { lblProgress.Text = "Erreur"; MessageBox.Show("Erreur: " + e.Error.Message); } else { lblProgress.Text = "recherche terminée"; } //Remise à zéro des compteurs progressBar1.Value = 0; incr = -1; incrPrgBar = 0; } private void BTN_ListeImages_Click(object sender, EventArgs e) { LV_AlbPho.Items.Clear(); imageList_Folder.Images.Clear(); //les ligne commentées ne sont plus nécessaire, elle sont dans USER_Photos() //LV_AlbPho.View = View.LargeIcon; //imageList_Folder.ImageSize = new Size(240, 240); //imageList_Folder.ColorDepth = ColorDepth.Depth16Bit; //LV_AlbPho.LargeImageList = imageList_Folder; //LV_AlbPho.SmallImageList = imageList_Folder; backgroundWorker1.RunWorkerAsync(); } } //////////////////////////////////////////////////////////// //ATTENTION CE QUI SUIT EST UNE CLASS QUI DOIT ETRE PLACÉ DANS LE MEME NAMESPACE MAIS //EN DEHORS DES AUTRES CLASS,Elle VA PERMETTRE D'AJOUTER DES EXTENTION SUPLÉMENTAIRE AUX CONTROLS //AINSI ON VA POUVOIR ACTIVER LE DOUBLEBUFFER SUR LE LISTVIEW, CE QUI A POUR EFFET DE RÉDUIRE LE //SCINTILLEMENT A L'AFFICHAGE SURTOUT PENDANT LE CHARGEMENT,CHOUETTE. //DES A PRÉSENT VOUS POUVEZ Y ACCEDER EN TAPANT ListView. // public static class ControlExtentions { // /// <summary> /// Methode d'extention doubleBuffer pour les controls /// Ne pas oublier d'ajouter la reference: using System.Reflection , en début de fichier; /// </summary> /// <param name="control"></param> /// <param name="enable"></param> internal static void DoubleBuffered(this Control control, bool enable) { var dB_PropInfo = control.GetType().GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic); dB_PropInfo.SetValue(control, enable, null); } } } ////////EXTENSION BONUS N' A PAS ÉTÉ UTILISÉ DE VOTRE CODE//////////////////////////// // /// <summary> ///// Extension pour les control pour Invoquer si nécessaire ///// </summary> ///// <typeparam name="T"></typeparam> ///// <param name="c"></param> ///// <param name="action"></param> //internal static void InvokeIfRequired<T>(this T c, Action<T> action) where T : Control //{ // if (c.InvokeRequired) // { // c.Invoke(new Action(() => action(c))); // } // else // { // action(c); // } //} ////POUR SE SERVIR DE L'EXTENSION InvokeIfRequired() PAR EXEMPLE : //private static void AddImageToImageList(ListView lv, Image img) //{ // if (lv.InvokeRequired) // { // //Alors Invoke Exécute le délégué spécifié qui exécute cette même méthode // lv.Invoke((MethodInvoker)delegate () { AddImageToImageList(lv, img); }); // } // else // { // //Ici votre code ajouter des images a ImageList // } //} ////////////////////////////////////////////////////////////////////////////////////////





    LENILAM







    • Marqué comme réponse Kulte7astKlub mardi 3 novembre 2020 15:23
    • Modifié Dragonix vendredi 16 juillet 2021 17:09
    mardi 3 novembre 2020 00:12

Toutes les réponses

  • Bonjour,

    Je suppose que le code suivant dans la fonction ScanDirectory peut-être cause le problème et il n'est pas nécessaire:

     foreach (var dir in Directory.GetDirectories(directory))
                    {
                        ScanDirectory(dir, searchPattern);
                    }

    Vous pouvez récupérer les répertoires et les sous-répertoires  qui correspondent au modèle de recherche spécifié en utilisant la méthode GetDirectories(String, String, SearchOption) dans l'événement BackgroundWorker1_DoWork. Par exemple: 

    string[] dirs = Directory.GetDirectories(RootPathPhotos, txtSearch.Text, SearchOption.AllDirectories);


    Cordialement,
    Nina

    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.


    lundi 28 septembre 2020 09:20
    Modérateur
  • Bonjour, Ahoj Nina,

    J'ai essaye avec les modifications que vous m'avez indique.

    Les photos s'affichent bien progressivent et correctement, mais la progressbar n'affiche rien, et l'application reste bloquee (impossible de bouger la fenetre UI pendant le chargement et l'affichage des photos).

    Je ne sais plus comment faire..... j'ai essaye plusieurs codes mais rien n'y fait, et je ne suis pas assez experimente pour resoudre mon probleme.

    je n'ai pas trouver d'exemples de codes sur internet qui fonctionnent et qui m'aident.

    Merci quand meme pour votre aide. C'est gentil de m'avoir repondu.


    lundi 28 septembre 2020 13:22
  • Salut, le post date de un mois facile mais bon tu seras peut être toujours intéressé par ces infos

    je tiens a signaler que je ne suis pas un professionnel.

    Donc pour résumer tes questions pour le blocage de l'app c'est du a un bout de code mis au mauvais endroit dans la méthode AddToListView:

    imageList_Folder.Images.Add(Image.FromFile(image));

    en fait il faut créer l'image en dehors du Invoke et la stocker dans un objet Image et passé l'objet en paramètre

    en dehors du Invoke:

    Image img=Image.FromFile(image);

    et ensuite dans le Invoke

    imageList_Folder.Images.Add(Image.FromFile(img));

    Pour la methode BackgroundWorker_DoWork()

    il y a deux fois la méthode ScanDirectory, bizarre, peut être que tu testais différentes solution

    celle qui se trouve dans la boucle ne s'exécutera jamais si il n'y a pas de sous dossier dans le path sélectionné,vu que tu utilises GetDirectory.Length pour la boucle, du coup la progressbar ne fonctionnera pas

    et pour finir il y a d'autre petites erreurs,mais qui n' en fait pas, on apprends de ces erreurs

    Du coup j' ai pris ton code et je t’ai mis des commentaires sur les changement minimum effectuées, tu pourras ensuite virer le code commenté inutile

    Il y a bien sur pas mal de chose a coder comme par exemple empêcher de cliquer sur le bouton avant que la tache soit fini,sinon erreur.

    Voila, j'espère que ça t'aidera.

    De mon coté du coup j'ai passé le weekend à faire évoluer ton bout de code et c'est pas terminé,merci pour l'idée j'avais jamais utilisé le ListView qui d'ailleur est bien relou au niveau de son fonctionnement. Si tu souhaites voir ce que j'ai codé de mon coté dis le moi je l'ai dépot sur GIT, je sais pas trop comment on donne accès a quelqu'un mais on verra ça, suis tout nouveau sur git,et tout in english, @++ peut être

    Voici ton code commenté: il y a des using a ajouter, de tout façcon visual te l'indiquera

    using System.Reflection; using System.Threading.Tasks; public USER_Photos() { InitializeComponent(); backgroundWorker1.WorkerReportsProgress = true; backgroundWorker1.WorkerSupportsCancellation = true; backgroundWorker1.DoWork += BackgroundWorker1_DoWork; backgroundWorker1.ProgressChanged += BackgroundWorker1_ProgressChanged; backgroundWorker1.RunWorkerCompleted += BackgroundWorker1_RunWorkerCompleted; //Code enlevé de methode bouton_Click,comme ça on a une initialisation et //configuration par défaut de ListView et ImageList,sachant que si vous souhaitez //utiliser la vue SmallIcon,List,ou détails du ListView, il faudra avoir un 2eme composant //ImageList deppuis le designer,ou declarer une nouvelle instance de ImageList dans le code LV_AlbPho.View = View.LargeIcon; imageList_Folder.ImageSize = new Size(240, 240); imageList_Folder.ColorDepth = ColorDepth.Depth32Bit; LV_AlbPho.LargeImageList = imageList_Folder; LV_AlbPho.SmallImageList = imageList_Folder; LV_AlbPho.ArrangeIcons(ListViewAlignment.SnapToGrid); LV_AlbPho.AutoArrange = true; //Ativation du DoubleBuffer pour réduire les scintillements lor du remplissage du tableau //en utilisant une méthode d'extension qui se trouve tout en bas du code dans une class à part LV_AlbPho.DoubleBuffered(true); } BackgroundWorker backgroundWorker1=new BackgroundWorker();

    //La si tu avais utilisé un composant ImageList depuis la boite à outil en mode design

    // tu n'as pas a mettre cette ligne la qui instancie un objet ImageList ImageList imageList_Folder = new ImageList(); //variable ajouté int incr = -1; //valeur d'incrément utilisé dans AddToListView() pour les items int incrPrgBar=0; //valeur d'incrément pour la progressbar // ici faut remettre un path valide bien sûr := public string RootPathPhotos = (@"Pictures").ToString(); public void ScanDirectory(string directory, string searchPattern) { //total fichier du repértoire float nbtfile = Directory.GetFiles(directory).Length; int pct = 0;//pourcentage try { foreach (var file in Directory.GetFiles(directory)) { ///////////////////code de progression /////////////////// //exécuté avant traitement fichier au cas ou un catch exécuté incrPrgBar += 1; if (backgroundWorker1.CancellationPending) { return; } pct = (int)(incrPrgBar / nbtfile * 100); lblProgress.Invoke((Action)(() => lblProgress.Text = file)); backgroundWorker1.ReportProgress(pct); // ca c'est pour le rafraichissement net de la progressbar quand le scan // est rapide car la pattern ne match pas,donc exécution de la boucle code rapide //peut etre mis en commentaire System.Threading.Thread.Sleep(2); //////////////////////////////////////////////// if (file.Contains(searchPattern)) { try { AddToListView(file); } catch (Exception) { //si file n'est pas une image,corrompu,ou pas pris en charge par le ListView on poursuit continue; } } } foreach (var dir in Directory.GetDirectories(directory)) { incrPrgBar = 0;//scan nouveau repertoire =compteur à zéro de progressbar try { ScanDirectory(dir, searchPattern); } catch (Exception) { //si file n'est pas une image,corrompu,ou pas pris en charge par le ListView on poursuit continue; } } } catch (Exception x) { MessageBox.Show(x.Message); } } public void AddToListView(String image) { //pour le texte affiché pour l'image string finfo = new FileInfo(image).Name; //On créer l'image bitmap en dehors du Invoke, Sionon c'est ça qui bloque l'app Image img = Image.FromFile(image); LV_AlbPho.Invoke((Action)(() => { //peut être désactivé //LV_AlbPho.BeginUpdate(); //cette ligne efface tout les éleméments, c' eest pas ce qu'on veut //LV_AlbPho.Clear(); //La ligne de code qui suit ce commentaire ne doit pas être ici: //Propiété View détermine dans quel mode le ListView va afficher les images //donc on doit définir ou changer sa propriété avant de remplir le ListView //cette propriété utilise soit l'objet LargeImageList quand View=View.LargeIcon //soit SmallImageList dans les modes View.SmallIcon , View.Détail, View.List //cependant,si on souhataite passer de LargeIcon à SmallIcon à tout moment,c'est possible

    //avec un bouton ou menu,et on placera ce code dans la méthode on_Click

    //LV_AlbPho.View = View.LargeIcon; //les 2 lignes suivante sont des propiétés qui n'ont pas à être redéfini pour chaque image //affectée a l'objet ImageList, se sont les propiétés de l'objet ImageList,dailleur elles //ne doivent pas changer pour remplir l'objet d'image //imageList_Folder.ImageSize = new Size(240, 240); //imageList_Folder.ColorDepth = ColorDepth.Depth16Bit; imageList_Folder.Images.Add(img); LV_AlbPho.Items.Add(finfo, incr += 1); //La boucle remplacé par la ligne du dessus,car inutile de réaffecter tout les valeurs //for (int _index = 0; _index < imageList_Folder.Images.Count; _index++) //{ // var item = new ListViewItem(); // item.ImageIndex = _index; // LV_AlbPho.Items.Add(item); //} //la ligne de code qui suit ce commentaire ne doit pas être ici: //La propiété LargeImageList utilise l'objet imageList_Folder qui contient les images //il doit donc être défini avant toute exécution de code dont la tache sera de remplir le //l'objet ImageList,c'est pourquoi on affectera l'objet à cette propiété en dehors des //méthodes de remplissage de l'objet,par exemple dans le public Form1() si vous avez //implémenté l'objet ImageList vous même,ou si vous avez utilisé la boite à outil pour //déposer un composant ImageList,alors à partir du panneau des propiétés du composant //ListView,affectez la propiété LargeImageList avec le composant ImageList. //Note: Le fait de remplir l'objet ImageList va rafrichir le ListView au fur et a mesure //LV_AlbPho.LargeImageList = imageList_Folder; // //la ligne de code qui suit ce commentaire ne fait pas ce qui est souhaitez, //étant donné que vous avez définicomme maximum de votre progressbar le nombre //de repertoires trouvés,hors la méthode dans laquelle nous sommes est appelée //pour chaque image trouvé //backgroundWorker1.ReportProgress(100); //peut être désactivé //LV_AlbPho.EndUpdate(); })); } private void BackgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { string[] dirs = Directory.GetDirectories(RootPathPhotos); //Plus nécessaire ProgressBar est géré dans la méthode ScanDirectory //float length = (dirs.Length == 0) ? 1 : dirs.Length; //progressBar1.Invoke((Action)(() => progressBar1.Maximum = (int)length)); //Ptete qui faudrait un try la mais bon y en a déja dans la méthode ScanDirectory(RootPathPhotos, txtSearch.Text); //cette boucle non plus, n'est plus nécessaire //for (int i = 0; i <= dirs.Length; i++) //{ // backgroundWorker1.ReportProgress((int)(i / length * 100)); // ScanDirectory(dirs[i], txtSearch.Text); //} backgroundWorker1.ReportProgress(100); } private void BackgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { if (!backgroundWorker1.CancellationPending) { //ici on récupère le pourcentage lblPercent.Text = e.ProgressPercentage + "%"; progressBar1.Value= e.ProgressPercentage; } } private void BackgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { //La comprend pas le raisonnement enfin si mais alors c'est un = et pas < a mon avis // //if (progressBar1.Value < progressBar1.Maximum) //{ // lblProgress.Text = "ok" + lblProgress.Text; //} //vu que cette méthode est déclenché par évenement tache terminé ou annulé le mieux a mon avis //c'est de gérer les évenements et au pire initialiser ce qui doit l'être if (e.Cancelled) { lblProgress.Text = "recherche arrêtée"; } else if (e.Error != null) { lblProgress.Text = "Erreur"; MessageBox.Show("Erreur: " + e.Error.Message); } else { lblProgress.Text = "recherche terminée"; } //Remise à zéro des compteurs progressBar1.Value = 0; incr = -1; incrPrgBar = 0; } private void BTN_ListeImages_Click(object sender, EventArgs e) { LV_AlbPho.Items.Clear(); imageList_Folder.Images.Clear(); //les ligne commentées ne sont plus nécessaire, elle sont dans USER_Photos() //LV_AlbPho.View = View.LargeIcon; //imageList_Folder.ImageSize = new Size(240, 240); //imageList_Folder.ColorDepth = ColorDepth.Depth16Bit; //LV_AlbPho.LargeImageList = imageList_Folder; //LV_AlbPho.SmallImageList = imageList_Folder; backgroundWorker1.RunWorkerAsync(); } } //////////////////////////////////////////////////////////// //ATTENTION CE QUI SUIT EST UNE CLASS QUI DOIT ETRE PLACÉ DANS LE MEME NAMESPACE MAIS //EN DEHORS DES AUTRES CLASS,Elle VA PERMETTRE D'AJOUTER DES EXTENTION SUPLÉMENTAIRE AUX CONTROLS //AINSI ON VA POUVOIR ACTIVER LE DOUBLEBUFFER SUR LE LISTVIEW, CE QUI A POUR EFFET DE RÉDUIRE LE //SCINTILLEMENT A L'AFFICHAGE SURTOUT PENDANT LE CHARGEMENT,CHOUETTE. //DES A PRÉSENT VOUS POUVEZ Y ACCEDER EN TAPANT ListView. // public static class ControlExtentions { // /// <summary> /// Methode d'extention doubleBuffer pour les controls /// Ne pas oublier d'ajouter la reference: using System.Reflection , en début de fichier; /// </summary> /// <param name="control"></param> /// <param name="enable"></param> internal static void DoubleBuffered(this Control control, bool enable) { var dB_PropInfo = control.GetType().GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic); dB_PropInfo.SetValue(control, enable, null); } } } ////////EXTENSION BONUS N' A PAS ÉTÉ UTILISÉ DE VOTRE CODE//////////////////////////// // /// <summary> ///// Extension pour les control pour Invoquer si nécessaire ///// </summary> ///// <typeparam name="T"></typeparam> ///// <param name="c"></param> ///// <param name="action"></param> //internal static void InvokeIfRequired<T>(this T c, Action<T> action) where T : Control //{ // if (c.InvokeRequired) // { // c.Invoke(new Action(() => action(c))); // } // else // { // action(c); // } //} ////POUR SE SERVIR DE L'EXTENSION InvokeIfRequired() PAR EXEMPLE : //private static void AddImageToImageList(ListView lv, Image img) //{ // if (lv.InvokeRequired) // { // //Alors Invoke Exécute le délégué spécifié qui exécute cette même méthode // lv.Invoke((MethodInvoker)delegate () { AddImageToImageList(lv, img); }); // } // else // { // //Ici votre code ajouter des images a ImageList // } //} ////////////////////////////////////////////////////////////////////////////////////////





    LENILAM







    • Marqué comme réponse Kulte7astKlub mardi 3 novembre 2020 15:23
    • Modifié Dragonix vendredi 16 juillet 2021 17:09
    mardi 3 novembre 2020 00:12
  • Tu es genial, ton code fonctionne a la perfection.

    L'application de ne fige pas lors du chargement des photos, la barre de progression fonctionne correctement.

    C'est tout a fait ce que je cherchais a faire. Un tres grand merci a toi.

    Je cree une application qui va gerer les documents medias d'un disque dur externe vendu avec l'application. cette application va gerer pas mal de choses (audio, videos, photos, dossiers, contacts, scannage de document, gestionnaire de mot de passe ainsi que d'autres modules).

    Une fois terminee, je serai heureux de t'offrir gratuitement l'application et un disque dur externe en remerciement. (ecris moi un mail afin que je garde ton contact).

    Mon site web www.digikofr.fr est pret mais offline car mon appli n'est pas terminee. J'espere finaliser tout ca en fevrier 2021 et ouvrir mon site.Tu peux me contacter sur ********

    J'ai aussi un site musical www.kulte7astklub.online si tu veux aller jeter un oeil.

    Encore un enorme merci pour ton travail et ton aide.



    mardi 3 novembre 2020 15:19
  • Slt, ok c'est noté je t'ai envoyé un mail sur ******* avec objet: contact Dragonix forum C# Visual Studio ...

    et merci pour la ta proposition de cadeau ,c ' est vraiment super généreux de ta part, on verra ça en 2021, j'espère que tu vas arriver à ce que tu veux.


    LENILAM


    vendredi 6 novembre 2020 15:34
  • et mon cadeau ;)  tu as réussi à faire ce que tu voulais?

    LENILAM

    vendredi 14 mai 2021 09:49
  • J'ai toujours pas fini l'application. Je ne t'ai pas oublie. :) J'essais d'implementer un client mail mais c'est pas facile. J'ai pu tester ton code, ca fonctionne, mais les photos sont decalees d'une photo (la dermiere photo ne s'affiche pas, juste le nom s'affiche) lorsque je lance pour la premiere fois le code. Si je relance l'affichage des photos une deuxieme fois, tout est correct. Tu as une idee ?
    jeudi 20 mai 2021 12:58
  • Slt,ton problème doit se situer au niveau de la déclaration de la valeur par défaut dans la déclaration de la variable "incr" qui est utilisée comme valeur d'incrémentation dans AddToListView() pour les items, donc étant donné que j' ai codé l'incrémentation

    LV_AlbPho.Items.Add(finfo, incr += 1);

    il faut donc en début de programme et à la fin du job affecter la valeur "-1" à la variable "incr", pour que ça commence bien à l'index "0" dans le:

    LV_AlbPho.Items.Add()

    Sinon vu que l'index c'est ce qui permet d'afficher les infos et l'emplacement de l'image correspondante dans le ListView, du coup si ça commence pas a "0" , tu auras décalage entre "emplacement réservé de l'image à afficher" et "emplacement des informations" dans le ListView. D' ailleurs si tu vérifies, tu devrais voir que les noms des images ne correspondent pas avec les images qu' il y a un décalage surement d'une image dans ton cas.

    Normalement dans le code que j'avais posté, ça fonctionne correctement, après je sais pas si tu as copié intégralement le code sans retouche ou que tu t'en ais inspiré.

    je mets en surbrillance dans le code des anciens posts le code et endroit concerné.


    LENILAM


    • Modifié Dragonix vendredi 16 juillet 2021 17:06
    vendredi 16 juillet 2021 16:58
  • Salut, j'ai mis

    incr = -1;
    incrPrgBar = 0;

    au début dans mon backgroundworker(dowork) et cela fonctionne correctement maintenant.

    Encore Merci. J'ai résolu un de mes soucis.

    mercredi 21 juillet 2021 14:09