none
Gif animé qui ne s'anime pas... RRS feed

  • Question

  • Bonjour,

    Plateforme : VS 2010 Ultimate, C#, Application Winform

    Contrôles concernés :

    - une PictureBox (picSpinner) contenant un gif animé qui matérialise le temps qui passe (spinner)

    - un WebBrowser (wb) qui affiche une page Internet

    Au clic sur un bouton Je souhaite rendre visible la PictureBox le temps que la page Internet se charge.

    Je fais donc dans le gestionnaire d'événement clic du bouton :

    picSpinner.Visible=True;

    picSpinner.Refresh();

    wb.Navigate(recherchePage());

    La pictureBox est rendue non visible dans le gestionnaire d'événement ProgressChanged du WebBrowser lorsque la page est chargée en totalité.

    La pictureBox s'affiche bien mais le gif ne s'anime pas (il ne figure donc plus le temps qui passe...). J'ai essayé de faire un Refreshsur la PictureBox dans le gestionnaire d'événement ProgressChanged du WebBrowser mais cela ne change rien car la latence de réponse se produit à la recherche de la page et non à son temps de chargement.

    Y a t-il une solution sans avoir à exécuter l'affichage de la pictureBox et la recherche de la page dans des Threads différents ?

    Merci

     

     

     


    Cordialement, Thierry

    mercredi 10 août 2011 10:16

Réponses

  • Bonjour,

    en effet cela ne fonctionne pas avex un

     System.Threading.Thread.Sleep(4000);
    il suffit de réécrire la fonction sleep et d'ajouter un Application.DoEvent() comme ceci:
    using System;
    using System.Windows.Forms;
    
    namespace cs_gif_anime
    {
     public partial class Form1 : Form
     {
      public Form1()
      {
       InitializeComponent();
      }
    
      private void Form1_Load(object sender, EventArgs e)
      {
       pictureBox1.Visible = false;
       button1.Text = "Turn On";
      }
    
      private void button1_Click(object sender, EventArgs e)
      {
       if (button1.Text == "Turn On")
       {
        pictureBox1.Visible = true;
        button1.Text = "Turn Off";
        pictureBox1.Refresh();
        sleep(4);
       }
       else
       {
        pictureBox1.Visible = false;
        button1.Text = "Turn On";
       }
      }
    
      private void sleep(int secondes)
      {
       Boolean depart = false;
       int secondeDepart = DateTime.Now.Second;
       while (depart == false)
       {
         DateTime maintenant = DateTime.Now;
         if (secondeDepart+secondes >= 60)
         {
          secondeDepart -= 60;
         }
         if (maintenant.Second == secondeDepart + secondes )
         {
           depart = true;
         }
         Application.DoEvents();
       }
      }
     }
    }
    


    fred
    • Proposé comme réponse fred75 mercredi 10 août 2011 21:12
    • Non proposé comme réponse -thierry- mercredi 10 août 2011 21:53
    • Marqué comme réponse Ciprian Duduiala mercredi 17 août 2011 06:01
    mercredi 10 août 2011 21:07

Toutes les réponses

  • Bonjour,

    J'ai créé un petit exemple et cela fonctionne sur mon pc (VS2010 express C#, application WinForm)

    Il faut mettre un gif anime dans pictureBox1

    using System;
    using System.Windows.Forms;
    namespace cs_gif_anime
    {
      public partial class Form1 : Form
      {
        public Form1()
        {
          InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
          pictureBox1.Visible = false;
          button1.Text = "Turn On";
        }
    
        private void button1_Click(object sender, EventArgs e)
        {
          if (button1.Text == "Turn On")
          {
            pictureBox1.Visible = true;
            button1.Text = "Turn Off";
          }
          else
          {
            pictureBox1.Visible = false;
            button1.Text = "Turn On";
          }
        }
      }
    }
    



    fred
    mercredi 10 août 2011 12:17
  • Bonjour,
    Merci pour la réponse mais votre exemple fonctionne car il n'y a pas de temps de latence.
    Si on le simule de la sorte :
     if (button1.Text == "Turn On")
     {
      pictureBox1.Visible = true;
      button1.Text = "Turn Off";
      pictureBox1.Refresh();
      System.Threading.Thread.Sleep(4000);
     }
    cela ne fonctionne plus...

    Ma question est donc comment faire sans faire un thread différent entre le traitement qui comporte ce temps de latence et l'affichage du gif animé...

    Merci

     

    Cordialement, Thierry



    mercredi 10 août 2011 13:52
  • Bonjour,

    en effet cela ne fonctionne pas avex un

     System.Threading.Thread.Sleep(4000);
    il suffit de réécrire la fonction sleep et d'ajouter un Application.DoEvent() comme ceci:
    using System;
    using System.Windows.Forms;
    
    namespace cs_gif_anime
    {
     public partial class Form1 : Form
     {
      public Form1()
      {
       InitializeComponent();
      }
    
      private void Form1_Load(object sender, EventArgs e)
      {
       pictureBox1.Visible = false;
       button1.Text = "Turn On";
      }
    
      private void button1_Click(object sender, EventArgs e)
      {
       if (button1.Text == "Turn On")
       {
        pictureBox1.Visible = true;
        button1.Text = "Turn Off";
        pictureBox1.Refresh();
        sleep(4);
       }
       else
       {
        pictureBox1.Visible = false;
        button1.Text = "Turn On";
       }
      }
    
      private void sleep(int secondes)
      {
       Boolean depart = false;
       int secondeDepart = DateTime.Now.Second;
       while (depart == false)
       {
         DateTime maintenant = DateTime.Now;
         if (secondeDepart+secondes >= 60)
         {
          secondeDepart -= 60;
         }
         if (maintenant.Second == secondeDepart + secondes )
         {
           depart = true;
         }
         Application.DoEvents();
       }
      }
     }
    }
    


    fred
    • Proposé comme réponse fred75 mercredi 10 août 2011 21:12
    • Non proposé comme réponse -thierry- mercredi 10 août 2011 21:53
    • Marqué comme réponse Ciprian Duduiala mercredi 17 août 2011 06:01
    mercredi 10 août 2011 21:07
  • Bonsoir,

    Le sleep n'était qu'un exemple pour simuler un temps de latence.

    Mon problème c'est que dans ma fonction rechercherPage() il y a un accès au net pour récupérer des infos via une API synchrone, c'est ce qui cause le temps de latence. Je ne peux donc pas utiliser Application.DoEvents()...

    Merci,

    Thierry


    Cordialement, Thierry
    mercredi 10 août 2011 21:53
  • Bonjour,

    Peux-tu nous montrer le code de l'API synchrone ?


    fred
    jeudi 11 août 2011 08:33
  • Bonjour, C'est une API exposée par le site Deezer, je n'ai donc pas accès au code. Je l'appelle simplement via la méthode ReadXML sur un Dataset en passant une URL en paramètre du genre : http://api-v3.deezer.com/1.0/search/artist/?q=queen&output=xml Je viens de penser à une solution qui consisterait à passer plutôt par un objet "WebClient" que par un dataset, de manière à faire un appel asynchrone. Du coup je dois pouvoir déclencher un refresh sur le picSpinner (ou un DoEvents) tantque la réponse du serveur n'est pas totalement arrivée. En revanche au lieu de récupérer un DataSet il va falloir que je parse mon document XML pour retrouver mes billes (ce sera plus laborieux, mais sûrement plus performant). Dès que j'ai le temps je teste ça... Merci bcp pour ton intérêt pour la question
    Cordialement, Thierry
    jeudi 11 août 2011 08:52
  • Bonjour,

    Je voulais dire que si une méthode (exemple System.Threadring.Thread.Sleep()) bloque l'affichage alors il suffit de réécrire la méthode ou de passer par une autre façon et d'inclure un DoEvents

    Je suis content d'avoir pu t'aider.

     


    fred
    jeudi 11 août 2011 17:33