[C#][WPF] Rafraichissement d'un System.Windows.Window

wperaud Messages postés 3 Date d'inscription lundi 29 juin 2009 Statut Membre Dernière intervention 30 juillet 2009 - 27 juil. 2009 à 10:24
wperaud Messages postés 3 Date d'inscription lundi 29 juin 2009 Statut Membre Dernière intervention 30 juillet 2009 - 30 juil. 2009 à 10:23
Bonjour,

j'ai été interpelé par un comportement d'une System.Windows.Window.

J'ai une fenetre avec un Control (ici, cas d'une ProgressBar).

Au click sur un bouton, j'aimerais que le composant devienne invisible, puis redevienne visible au bout de 3 secondes :

private void btnOk_Click(object sender, RoutedEventArgs e)
{
   progressBar1.Visibility = Visibility.Visible;

   System.Threading.Thread.Sleep(3000);

   progressBar1.Visibility = Visibility.Hidden;
}



Le problème, c'est que l'interface utilisateur n'est pas mise à jour. après le :
progressBar1.Visibility = Visibility.Visible;



L'interface n'est mise à jour qu'après les 3 secondes (vérification faite en enlevant le fait de cacher la ProgressBar.

J'aimerais comprendre ce comportement, qui me semble pourtant pas complexe du tout.
Merci

3 réponses

krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 49
27 juil. 2009 à 11:46
Salut.

Thread.Sleep endort le thread. C'est donc une opération plus ou moins bloquante. Elle l'est aussi pour le rafraichissement de ta fenêtre.
Tu peux utiliser un Timer, ça devrait marcher. Tu auras également besoin d'utiliser un Dispatcher pour accéder à ta progressbar depuis le thread créé par le timer.
L'autre solution, qui devrait également marcher (mais je ne garantis rien là encore), est d'utiliser un DoEvents avant de faire ton thread.sleep :

progressBar1.Visibility = Visibility.Visible;
Application.DoEvents();
Thread.Sleep(3000);
progressBar1.Visibility = Visibility.Hidden;


Cependant, la méthode DoEvents() n'existe pas directement en WPF. Tu peux donc regarder ici. En gros, le but de cette méthode est d'attendre le traitement de toutes les tâches graphiques.

Krimog : while (!(succeed = try())) ;
- NON, "LE BAR" n'est PAS un langage de programmation ! -
0
wperaud Messages postés 3 Date d'inscription lundi 29 juin 2009 Statut Membre Dernière intervention 30 juillet 2009
27 juil. 2009 à 15:09
Merci pour ta réponse.

Ne travaillant pas sur une Application mais sur une DLL, j'ai laissé de coté la solution du DoEvents();

Je vais apporter quelques précisions, cela sera plus pratique pour trouver une solution.

J'ai 3 méthodes :
- private void btnOk_Click(object sender, RoutedEventArgs e)
- private void checkInfo()
- private void updateGUI(Boolean value)

Lors du click sur le bouton OK, je mets à jour l'interface graphique en appelant la méthode updatgeGUI(false) afin de faire patienter l'utilisateur (apparition d'une progressBar, etc)

J'appelle ensuite la méthode checkInfo() qui est une méthode dont je ne connais pas la durée. Dans mon premier post, Thread.Sleep n'est là que pour simuler le fait que je réalise un traitement dont je ne connais pas la durée.

Une fois ce traitement réalisé, je modifie à nouveau l'interface graphique en appelant updatgeGUI(true).

Je pensais utiliser un delegate, afin d'appeler la méthode checkInfo() de manière asynchrone, avec une méthode de CallBack qui appelerait updatgeGUI(true).

Cela marche, sauf que le thread créé par le delegate n'a pas accès aux éléments de ma fenêtre.
J'ai commencé à me renseigné sur les Dispatcher que je ne connaissais pas. Par contre, je ne vois pas encore comment l'utiliser dans mon cas.
0
wperaud Messages postés 3 Date d'inscription lundi 29 juin 2009 Statut Membre Dernière intervention 30 juillet 2009
30 juil. 2009 à 10:23
Merci encore :)

J'ai trouvé une solution :
ThreadPool.QueueUserWorkItem(delegate
{
   checkInfo();

   Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate
   {
      afterCheck();
   });
});
0
Rejoignez-nous