Bonjour,

Jusqu'à présent, je code en C# en utilisant seulement les bases du langage. Du coup, je dois certainement utiliser parfois un marteau pilon pour enfoncer un clou voir coder un peu salement !

Et pour la première fois, j'ai besoin de faire un traitement assez long ce qui gel mon interface pendant 5/6 secondes. J'ai donc mis en place une barre de progression et, comme j'ai pu m'en apercevoir sur les forums, je suis tombé dans le panneau comme tout débutant en la matière : mon interface reste gelé et ma barre de progression ne progresse pas...

Je me suis donc penché sur les backgroundworker qui, au premier abord, ne semblent pas compliqués à mettre en place.
De fait, il fonctionne très bien : j'ai créé une méthode (TraitementDocumentsAsync) dans lequel j'ai tout mis, même les événements liés à DoWork, ProgressChanged et RunWorkerCompleted (là, je ne sais pas si j'ai bien fait). Cette méthode permet dans un premier temps de scanner un dossier pour savoir si de nouveaux fichiers ont été placés là, puis de vérifier si les fichiers déjà connus sont encore présents et enfin de constituer une liste qui va me servir pour le binding d'une listview. J'appelle cette méthode dans l'événement loaded de ma fenêtre et ça fonctionne nickel. A noter que ma liste pour le binding est déclarée en variable de classe : List<LesDocuments> LesDocs = new List<LesDocuments>();

J'ai également prévu un bouton "Rafraîchissement" qui permet de relancer le même traitement en appelant à nouveau ma méthode TraitementDocumentsAsync. Et c'est là que se pose mon problème : ma base (SQLite) se met bien à jour mais ma listview reste bloquée sur les anciennes données. Pourquoi cela fonctionne en lançant la méthode dans l'événement loaded de ma fenêtre mais pas dans l'événement click de mon bouton ?

Voici le code de la méthode contenant le backgroundworker :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
        private void TraitementDocumentsAsync()
        {   // Permet de rechercher les nouveaux documents puis des rechercher les anomalies :
            Para P = new Para();
            DlgBarreProgression MaDlgBP = new DlgBarreProgression();
            MaDlgBP.BarreProgression.Value = 0;
            MaDlgBP.BarreProgression.Maximum = 300;
            MaDlgBP.Show();
 
            BackgroundWorker Traitements = new BackgroundWorker();
            Traitements.WorkerReportsProgress = true;
            Traitements.DoWork += Traitements_AFaire;
            Traitements.ProgressChanged += Traitements_ChangementProgres;
            Traitements.RunWorkerCompleted += Traitements_Fin;
            Traitements.RunWorkerAsync();
 
            void Traitements_AFaire(object sender, DoWorkEventArgs e)
            {
                Int32 NbFichiersTotal = 0;
                Int32 i = 0;
                Int32 ProgressionPourcentage = 0;
 
                // Recherches des nouveaux fichiers :
                   ...   // Ces instructions ne posant pas de problème, je les ai enlevés pour poster pour ne pas la visibilité
 
                // Recherches des anomalies :
                    ...  // Idem
                }
 
                // Initialisation binding :
                if (Directory.Exists(new Para().AdresseDossierActes))
                {
                    i = 0;
                    List<Document> LesDocs1 = Liste.ListeDocuments();
                    NbFichiersTotal = LesDocs1.Count();                    
                    foreach (Document UnDoc in LesDocs1.OrderBy(Elt => Elt.Nom))
                    {
                        i++;
                        UnDoc.Enregistrer();
                        LesDocs.Add(new LesDocuments()
                        {
                            Id = UnDoc.Id,
                            TypeDoc = new DocType(UnDoc.IdType).Type,
                            Nom = @UnDoc.Nom.Replace("_", "__"),
                            NbPersonnes = UnDoc.ListeIdPersonnes().Count.ToString(),
                            Anomalie = UnDoc.Anomalie
                        });
                        ProgressionPourcentage = Convert.ToInt32(200 + 100 * i / NbFichiersTotal);
                        (sender as BackgroundWorker).ReportProgress(ProgressionPourcentage);
                    }
                }
                else (sender as BackgroundWorker).ReportProgress(300);
            }
 
            void Traitements_ChangementProgres(object sender, ProgressChangedEventArgs e)
            {   // Pour envoyer l'état de la progression du traitement :
                MaDlgBP.BarreProgression.Value = e.ProgressPercentage;
                if (e.ProgressPercentage < 101) MaDlgBP.LblInformations.Content = "Recherche des nouveaux fichiers...";
                if (e.ProgressPercentage > 100 && e.ProgressPercentage < 201) MaDlgBP.LblInformations.Content = "Recherche d'anomalies...";
                if (e.ProgressPercentage > 200) MaDlgBP.LblInformations.Content = "Initialisation de la liste...";
                MaDlgBP.LblPourcentage.Content = e.ProgressPercentage / 3 + " %";
            }
 
            void Traitements_Fin(object sender, RunWorkerCompletedEventArgs e)
            {   // Fin du traitement :
                InitDossier();
                InitListeDocuments();
                InitDocumentType();
                InitDocumentSelect();
                InitNbCaracteres();
                InitBoutons();
                MaDlgBP.Close();
            }
        }
 
       private void InitListeDocuments()
        {   // Initialisation de la liste des documents :
            if (Directory.Exists(new Para().AdresseDossierActes))
            {
                LvwDocuments.ItemsSource = LesDocs;
                LvwDocuments.SelectedItem = LvwDocuments.Items.Cast<LesDocuments>().FirstOrDefault(Elt => Elt.Id == IdDocSelect);
            }
        }
 
       private void BtnRafraichir_Click(object sender, RoutedEventArgs e)
        {
            TraitementDocumentsAsync();
        }
 
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            TraitementDocumentsAsync();
        }
D'habitude, lorsque je veux "rafraîchir" ma listview, je reconstitue ma liste (LesDocs) puis je la ré-assigne avec un MaListView.ItemsSource = MaListe; Là, j'ai l'impression que cette façon de faire ne fonctionne pas avec un backgroundworker.

Merci d'avance pour vos réponses.