IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Forms Discussion :

[C#] Barre de défilement et mise à jour de fenetre [Débutant(e)]


Sujet :

Windows Forms

  1. #1
    Membre confirmé
    Inscrit en
    Août 2003
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Août 2003
    Messages : 53
    Par défaut [C#] Barre de défilement et mise à jour de fenetre
    J'analyse un énorme fichier binaire en c#, et je voudrais savoir comment mettre une barre de défilement pour que l'on puisse voir la progression du traitement. Pour le moment, mon code est le suivant :

    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
            private void openFileDialog1_FileOk_1(object sender, CancelEventArgs e)
            {
                this.Activate();
                string file_name = openFileDialog1.FileName;
     
                System.IO.FileInfo fileInfo = new System.IO.FileInfo(file_name);
                System.IO.FileStream fileStream = fileInfo.OpenRead();
     
                if (fileStream.CanRead)
                {
                    richTextBox1.Clear();
                    System.IO.BinaryReader bReader = new System.IO.BinaryReader(fileStream, System.Text.Encoding.UTF7);
     
                    try
                    {
                        byte[] m_typ_tab;
                        ushort[] m_tail_tab;
                        byte m_nb_tab = lecture_entete(bReader, out m_typ_tab, out m_tail_tab);
     
                        //Lecture des tableaux
                        for (int i = 0; i < m_nb_tab; i++)
                        {
                            switch (m_typ_tab[i])
                            {
                                case 1: lecture_table1(bReader); break;
                                case 2: lecture_table2(bReader); break;
                                case 3: lecture_table3(bReader); break;
                                case 4: lecture_table4(bReader); break;
                                default: Console.WriteLine("Invalid Table Type... This table will be ignored"); break;
                            }
                        }
     
                    }
                    finally
                    {
                        bReader.Close();
                    }
                }
                else
                    Console.WriteLine("File unreadable!");
                fileStream.Close();
            }
    Pour l'instant, le problème est que lorsque je clique sur le bouton "Ouvrir" de mon OpenFileDialog, le système n'a plus aucune réactivité (la fenetre principale est blanche en arriere plan, et l'OpenFileDialog est figée), jusqu'à ce que le traitement soit fini... du coup, on ne sait pas si l'appli est plantée en analysant le fichier, ou si elle tourne correctement. J'aimerais que la barre défile en fonction de notre position dans le fichier, et que la fenetre se rafraichisse.

    Merci d'avance pour votre aide

  2. #2
    Membre Expert
    Avatar de freddyboy
    Homme Profil pro
    Architecte technique
    Inscrit en
    Novembre 2003
    Messages
    810
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Novembre 2003
    Messages : 810
    Par défaut
    tu trouvera un exmple de barre de progression ici : http://dotnet.developpez.com/sources...gressBarWindow

    ensuite, il faudrait mettre le traitement de ton fichier dans un thread comme cela ton interface graphique ne sera pas bloquée.

    @+

  3. #3
    Membre confirmé
    Inscrit en
    Août 2003
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Août 2003
    Messages : 53
    Par défaut
    Je regarde ça lundi au boulot, et je te tiens au courant
    Merci en tout cas

  4. #4
    Membre confirmé
    Inscrit en
    Août 2003
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Août 2003
    Messages : 53
    Par défaut
    Euh... c'est justement le problème du thread que je sais pas faire!!! L'exemple que tu me montres est l'exemple bateau de progression d'une barre toute bête.

    J'ai appliqué des threads à mon programme. Mais je suis confronté à un problème : comment savoir que mon thread de traitement est fini sans avoir à bloquer le père? Car quand le traitement est fini, je veux faire afficher par le père la string créée par son fils, sans toutefois que le père se bloque...

    Voici le code du handle du thread fils :
    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
     
        public class LectureFichierThreadHandle
        {
            private string file_name;
            public string display;
     
            public LectureFichierThreadHandle(string _file_name)
            {
                file_name = _file_name;
            }
     
            public void lecture_fichier()
            {
                FileInfo fileInfo = new FileInfo(file_name);
                FileStream fileStream = fileInfo.OpenRead();
     
                if (fileStream.CanRead)
                {
                    BinaryReader bReader = new BinaryReader(fileStream, System.Text.Encoding.UTF7);
                    try
                    {
                        byte[] m_typ_tab;
                        ushort[] m_tail_tab;
                        byte m_nb_tab = lecture_entete(bReader, out m_typ_tab, out m_tail_tab);
     
                        //Lecture des tableaux
                        for (int i = 0; i < m_nb_tab; i++)
                        {
                            switch (m_typ_tab[i])
                            {
                                case 1: lecture_table1(bReader); break;
                                case 2: lecture_table2(bReader); break;
                                case 3: lecture_table3(bReader); break;
                                case 4: lecture_table4(bReader); break;
                                default: Console.WriteLine("Invalid Table Type... This table will be ignored"); break;
                            }
                        }
     
                    }
                    finally
                    {
                        bReader.Close();
                    }
                }
                else
                    Console.WriteLine("File unreadable!");
                fileStream.Close();
     
                Thread.CurrentThread.Abort();
            }
     
            private byte lecture_entete(BinaryReader bReader, out byte[] m_typ_tab, out ushort[] m_tail_tab)
            {
             }
     
            //Table des données d'identification 
            private void lecture_table1(BinaryReader bReader)
            {
            }
     
            //Table des données de tranches
            private void lecture_table2(BinaryReader bReader)
            {
            }
     
            //Tables de données utilisateurs
            private void lecture_table3(BinaryReader bReader)
            {
            }
     
            //Tables de données de perturbographie
            private void lecture_table4(BinaryReader bReader)
            {
            }
     
        }
    Et voici le code du programme appelant :
    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
        partial class Form1 : Form
        {
            private const string Form_Title = "Lecteur ECCD.SAD";
     
            public Form1()
            {
                InitializeComponent();
                this.Text = Form_Title;
            }
     
            private void openToolStripMenuItem_Click(object sender, EventArgs e)
            {
                openFileDialog1.ShowDialog();
            }
     
            private void openFileDialog1_FileOk_1(object sender, CancelEventArgs e)
            {
                this.Activate();
     
                LectureFichierThreadHandle lfThreadHandle = new LectureFichierThreadHandle(openFileDialog1.FileName);
                Thread lectureThread = new Thread(new ThreadStart(lfThreadHandle.lecture_fichier));
                lectureThread.Start();
     
                lectureThread.Join();
                richTextBox1.Text = lfThreadHandle.display;
            }
        }
    Ici on voit bien que j'affiche mon texte simplement après le join, ce qui bloque mon processus père... Or ce processus père devra entre autre afficher une barre de défilement, une possibilité de faire un "suspend" et un "resume" etc...

  5. #5
    Rédacteur
    Avatar de dev01
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    2 451
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 451
    Par défaut
    Salut !

    tu peux aussi appeller à intervale régulier (par exemple si tu lit ton fichier dans une boucle )
    la fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Application.DoEvents();
    elle permet de faire passer les messages destiné à la fenetre. En gros elle stop le traitement en cours , fait passer les messages, et reprend le traitement .

    Et ça te permet de faire également ta barre de progression . Tu l'incrémente avant le DoEvent et comme ça elle se met à jour .

  6. #6
    Membre Expert
    Avatar de freddyboy
    Homme Profil pro
    Architecte technique
    Inscrit en
    Novembre 2003
    Messages
    810
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Novembre 2003
    Messages : 810
    Par défaut
    les threads ont une property IsAlive.
    sinon dans les cours : http://dotnet.developpez.com/cours/ tu as des artciles pour apprends les threads.

    @+

  7. #7
    Membre confirmé
    Inscrit en
    Août 2003
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Août 2003
    Messages : 53
    Par défaut
    En gros ma question était : comment passer le message de mort du fils au père, et comment passer un message d'évolution du fils au père du style : "j'en suis ici, mets à jour ta barre de progression".

    freddyboy
    Si tu avais regardé mon code, tu aurais vu qu'il est plus évolué que les exemples que tu viens de me montrer...
    En gros tu voudrais que je fasse une boucle infinie qui teste la propriété isAlive? Mais justement le principe est que le père fasse autre chose pendant ce temps!

    dev01
    La commande DoEvents doit certainement très bien marcher pour appliquer des évênements, mais comment je les crée et les appelle ces évênements?

  8. #8
    Membre Expert
    Avatar de freddyboy
    Homme Profil pro
    Architecte technique
    Inscrit en
    Novembre 2003
    Messages
    810
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Novembre 2003
    Messages : 810
    Par défaut
    ok sorry c'est vrai, j'avais pas trop lu le code mais avec la question je pensais que ton probleme etait simple.

    bon eventuellement, tu peux peut etre t'en sortir avec les delegates et les events. Ta classe fils doit contenir un delegate et un event, et elle envoie un message lors de la progression de lecture. ensuite le pere s'abonne au fils pour ecouter les evenements et ainsi recuperer ce que tu lui envoi.

    bon c'est une idee comme, c'est peut etre pas la meilleur mais c'est comme ca que je ferais ds un premier tps.

    @+

  9. #9
    Membre confirmé
    Inscrit en
    Août 2003
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Août 2003
    Messages : 53
    Par défaut
    Pourrai-je avoir plus d'explications? Comment faire exactement. Là j'y vais en tatonnant, mais je perds mon temps en ne sachant pas comment faire!

    Voici le code modifié sur tes conseils, mais ça provoque une erreur :


    Voici le code du handle du thread fils :
    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
     
       [b] public delegate void ProgressionHandler();[/b]
     
        public class LectureFichierThreadHandle
        {
            [b]public event ProgressionHandler ProgressEvent; [/b]
     
            private string file_name;
            public string display;
     
            public LectureFichierThreadHandle(string _file_name)
            {
                file_name = _file_name;
            }
     
            public void lecture_fichier()
            {
                FileInfo fileInfo = new FileInfo(file_name);
                FileStream fileStream = fileInfo.OpenRead();
     
                if (fileStream.CanRead)
                {
                    BinaryReader bReader = new BinaryReader(fileStream, System.Text.Encoding.UTF7);
                    try
                    {
                        byte[] m_typ_tab;
                        ushort[] m_tail_tab;
                        byte m_nb_tab = lecture_entete(bReader, out m_typ_tab, out m_tail_tab);
     
                        //Lecture des tableaux
                        for (int i = 0; i < m_nb_tab; i++)
                        {
                            switch (m_typ_tab[i])
                            {
                                case 1: lecture_table1(bReader); break;
                                case 2: lecture_table2(bReader); break;
                                case 3: lecture_table3(bReader); break;
                                case 4: lecture_table4(bReader); break;
                                default: Console.WriteLine("Invalid Table Type... This table will be ignored"); break;
                            }
                            [b]ProgressEvent();[/b]
                        }
     
                    }
                    finally
                    {
                        bReader.Close();
                    }
                }
                else
                    Console.WriteLine("File unreadable!");
                fileStream.Close();
     
                Thread.CurrentThread.Abort();
            }
     
            private byte lecture_entete(BinaryReader bReader, out byte[] m_typ_tab, out ushort[] m_tail_tab)
            {
             }
     
            //Table des données d'identification 
            private void lecture_table1(BinaryReader bReader)
            {
            }
     
            //Table des données de tranches
            private void lecture_table2(BinaryReader bReader)
            {
            }
     
            //Tables de données utilisateurs
            private void lecture_table3(BinaryReader bReader)
            {
            }
     
            //Tables de données de perturbographie
            private void lecture_table4(BinaryReader bReader)
            {
            }
     
        }
    Et voici le code du programme appelant :
    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
        partial class Form1 : Form
        {
            private const string Form_Title = "Lecteur ECCD.SAD";
     
            public Form1()
            {
                InitializeComponent();
                this.Text = Form_Title;
            }
     
            private void openToolStripMenuItem_Click(object sender, EventArgs e)
            {
                openFileDialog1.ShowDialog();
            }
     
            private void openFileDialog1_FileOk_1(object sender, CancelEventArgs e)
            {
                this.Activate();
     
                LectureFichierThreadHandle lfThreadHandle = new LectureFichierThreadHandle(openFileDialog1.FileName);
                [b]lfThreadHandle.ProgressEvent += new ProgressionHandler(OnThreadProgressEvent);[/b]
     
                Thread lectureThread = new Thread(new ThreadStart(lfThreadHandle.lecture_fichier));
                lectureThread.Start();
     
                lectureThread.Join();
                richTextBox1.Text = lfThreadHandle.display;
            }
     
    [b]        private void OnThreadProgressEvent()
            {
                richTextBox1.Text += "coucou";
            }
    [/b]    }
    Voici l'erreur :
    Illegal cross-thread operation: Control 'richTextBox1' accessed from a thread other than the thread it was created on.
    Au secours, j'y comprends rien!

  10. #10
    Membre Expert
    Avatar de freddyboy
    Homme Profil pro
    Architecte technique
    Inscrit en
    Novembre 2003
    Messages
    810
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Novembre 2003
    Messages : 810
    Par défaut
    si tu connais pas trop le fonctionnement des delegates je te conseil si tu as un peu de tps de lire ceci : http://csharpro.developpez.com/page10.php

    apres je pense que cela te semblera plus clair.

    @+

  11. #11
    Membre confirmé
    Inscrit en
    Août 2003
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Août 2003
    Messages : 53
    Par défaut
    Merci j'avance lentement mais surement

    Alors maintenant je parviens à transmettre des messages à mon thread père, et même à transmettre des variables

    Le seul problème reste le suivant : je peux utiliser dans ma méthode de réception d'évênement que des objets qui ne sont pas de la classe père

    Ce code marche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            private void OnThreadProgressEvent(string _display)
            {
                MessageBox.Show(_display);
            }
    Mais celui-là ne marche pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            private void OnThreadProgressEvent(string _display)
            {
                richTextBox1.Text += _display;
            }
    Il renvoie l'erreur :
    Illegal cross-thread operation: Control 'richTextBox1' accessed from a thread other than the thread it was created on.

    Une idée? Car c'est la seule chose qui me manque pour tout faire marcher

  12. #12
    Membre Expert
    Avatar de freddyboy
    Homme Profil pro
    Architecte technique
    Inscrit en
    Novembre 2003
    Messages
    810
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Novembre 2003
    Messages : 810
    Par défaut
    tu as essaye avec richtextbox.appendtext(_display) ?

    @+

  13. #13
    Membre confirmé
    Inscrit en
    Août 2003
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Août 2003
    Messages : 53
    Par défaut
    Même erreur...

  14. #14
    Membre Expert
    Avatar de freddyboy
    Homme Profil pro
    Architecte technique
    Inscrit en
    Novembre 2003
    Messages
    810
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Novembre 2003
    Messages : 810
    Par défaut
    ben la je sais pas trop, faudrait peut etre tester si ton thread est 'IsAlive'.

    @+

  15. #15
    Membre confirmé
    Inscrit en
    Août 2003
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Août 2003
    Messages : 53
    Par défaut
    Après maintes recherches, voici la solution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
            private void OnThreadProgressEvent(string _display)
            {
                if (richTextBox1.InvokeRequired)
                {
                    ProgressionHandler msgArrived = new ProgressionHandler(OnThreadProgressEvent);
                    this.Invoke(msgArrived, new object[] { _display });
                }
                else
                    richTextBox1.AppendText(_display);
            }
    En fait il faut se servir de l'InvokeRequired et de l'Invoke pour invoquer l'évênement à partir du thread père...

    Merci pour tes réponses rapides, elles ont largement contribue à me mettre sur la voie

  16. #16
    Membre Expert
    Avatar de freddyboy
    Homme Profil pro
    Architecte technique
    Inscrit en
    Novembre 2003
    Messages
    810
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Novembre 2003
    Messages : 810
    Par défaut
    felicitations, apres j'etais à court d'idées.

    @+

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 5
    Dernier message: 23/06/2014, 11h31
  2. Réponses: 1
    Dernier message: 31/03/2010, 16h57
  3. Mise à jour barre d'outil
    Par Tiolebucheron dans le forum Ext JS / Sencha
    Réponses: 2
    Dernier message: 21/07/2009, 13h11
  4. Mise à jour de Mandriva 2008.0 : barre de menu KDE disparue
    Par Auteur dans le forum Mandriva / Mageia
    Réponses: 2
    Dernier message: 09/05/2008, 23h47
  5. Mise à jour de la barre d'outil
    Par jackfred dans le forum Excel
    Réponses: 3
    Dernier message: 11/07/2007, 11h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo