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 Presentation Foundation Discussion :

WPF : Mise à jour d'un slider avec un Dispatcher


Sujet :

Windows Presentation Foundation

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Novembre 2006
    Messages
    79
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Novembre 2006
    Messages : 79
    Par défaut WPF : Mise à jour d'un slider avec un Dispatcher
    Bonjour,

    Dans une petit appli WPF de type lecteur MP3, je souhaite lier un contrôle de type Slider avec le déroulement d'un morceau MP3 (Lecteur.CurrentPosition).
    Lecteur étant un objet de la classe AudioVideoPlayBack.Audio
    Et CurrentPosition donnant la position courante en milliseconde (double) du morceau.


    Je tente donc de mettrer à jour le slider grâce à la classe Dispatcher, vu qu'en WPF, on ne peut accéder à slider.value en dehors du thread principal.

    Mais c'est sans effet. Le slider reste immobile, tandis que le morceau de musique est lu.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    private delegate void AppelMethodeDelegate();
            
            private void btnLecture_Click(object sender, RoutedEventArgs e)
            {
               
           CtrLecture._lire();
           AppelMethodeDelegate appel = new AppelMethodeDelegate(_derouler);
           sliderMorceau.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Send, appel);        }
    
    
            private void _derouler()
            {
                sliderMorceau.Value = CtrLecture.Lecteur.CurrentPosition;        }
    Je sais que plusieurs sujets ont été lancés concernant le multithreading, mais je n'ai rien trouvé qui réponde à mon besoin.

  2. #2
    Rédacteur
    Avatar de The_badger_man
    Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2005
    Messages
    2 745
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 745
    Par défaut
    Quand tu cliques sur le bouton de lecteure la méthode _derouler est appelé une fois. Elle ne va pas être appelée à chaque modification de la valeur CurrentPosition. Pour ça il faut s'abonner à l'évènement qui correspond à la modification de la valeur CurrentPosition.
    Les règles du forum
    Le trio magique : FAQ + Cours + fonction rechercher
    Mes articles
    Pas de questions par messages privés svp

    Software is never finished, only abandoned.

  3. #3
    Membre Expert
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    2 210
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 210
    Par défaut
    Salut,

    Par contre, AudioVideoPlayBack.Audio n'a pas l'air de proposer d'évènements de ce type... Peut-être faut-il s'orienter vers une autre lib.

    Si tu veux vraiment utiliser celle-ci ou si le but et de voir comment le Dispatcher fonctionne, tu peux t'en sortir ainsi :
    Code xml : 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
    <Window 
      x:Class="DispatcherAppliWpf.Window1"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Title="Window1" 
      Height="150" Width="300"
      >
     
      <Grid>
     
        <Grid.RowDefinitions>
          <RowDefinition Height="45" />
          <RowDefinition Height="*" />
          <RowDefinition Height="45" />
        </Grid.RowDefinitions>
     
        <Button x:Name="BtnPlay" Content=">" Click="BtnPlay_Click" />
     
        <Slider x:Name="SliderMorceau" Grid.Row="2" Margin="5" />
     
      </Grid>
     
    </Window>

    Code c# : 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
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
     
    using Microsoft.DirectX.AudioVideoPlayback;
    using System.Threading;
     
    namespace DispatcherAppliWpf {
     
      public partial class Window1 : Window {
     
        private Audio audio;
     
        public Window1() {
          InitializeComponent();
        }
     
        private delegate void AppelMethodeDelegate(double d);
     
        private void _derouler(double o) {
          SliderMorceau.Value = o;
        }
     
        private void BtnPlay_Click(object sender, RoutedEventArgs e) {
          audio = new Audio(@"C:\...\Son.mp3");
          audio.Starting += new EventHandler(audio_Starting);
          audio.Ending += new EventHandler(audio_Ending);
          SliderMorceau.Minimum = 0.0;
          SliderMorceau.Maximum = audio.Duration*10.0;
          audio.Play();
        }
     
        void audio_Starting(object sender, EventArgs e) {
          ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(Traitement), ((Audio)sender).Duration*10.0);
        }
     
        private void Traitement(object o) {
          for (double i = 0; i < (double)o; i++) {
            SliderMorceau.Dispatcher.BeginInvoke(new AppelMethodeDelegate(_derouler), System.Windows.Threading.DispatcherPriority.Send, i);
            Thread.Sleep(new TimeSpan(0, 0, 0, 0, 100));
          }
        }
     
        void audio_Ending(object sender, EventArgs e) {
          SliderMorceau.Value = SliderMorceau.Maximum;
        }
     
      }
     
    }

  4. #4
    Membre confirmé
    Inscrit en
    Novembre 2006
    Messages
    79
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Novembre 2006
    Messages : 79
    Par défaut morceau saccadé
    Merci à tous les 2 pour ces précisions.
    Concernant le code de Binoo, une petite erreur à priori, dans la fonction traitement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    private void Traitement(object o) {
          for (double i = 0; i < (double)o; i++) {
            SliderMorceau.Dispatcher.BeginInvoke(new AppelMethodeDelegate(_derouler), System.Windows.Threading.DispatcherPriority.Send, i);
            Thread.Sleep(new TimeSpan(0, 0, 0, 0, 100));
          }
        }
    La méthode BeginInvoke du Dispatcher prend en paramètre (DispatcherPriority, Delegate) et non pas l'inverse.
    http://msdn.microsoft.com/en-us/library/ms591206.aspx

    Cette erreur corrigée, le code fonctionne presques, car le slider se déroule mais le morceau est très saccadé.
    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
     
    public partial class DialogueIHMLecteur : Window
        {
            private ControleLecture CtrLecture = new ControleLecture();
            private delegate void AppelMethodeDelegate(double d);
     
     
            private void btnLecture_Click(object sender, RoutedEventArgs e)
            {
                CtrLecture.Lecteur.Starting += new EventHandler(_demmarrage);
                CtrLecture.Lecteur.Ending += new EventHandler(_fin);
                sliderMorceau.Minimum = 0.0;
                sliderMorceau.Maximum = CtrLecture.Lecteur.Duration * 10.0;
                CtrLecture._lire();
     
     
            }
     
     
            private void _derouler(double o)
            {
                sliderMorceau.Value = o;
            }
     
     
            void _demmarrage(object sender, EventArgs e)
            {
                ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(Traitement), ((Audio)sender).Duration * 10.0);
            }
     
            private void Traitement(object o)
            {
                for (double i = 0; i < (double)o; i++)
                {
                    sliderMorceau.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Send, new AppelMethodeDelegate(_derouler), i);
                    Thread.Sleep(new TimeSpan(0, 0, 0, 0, Int32.Parse(CtrLecture.Lecteur.Duration.ToString())));
                }
            }
     
     
            void _fin(object sender, EventArgs e)
            {
                sliderMorceau.Value = sliderMorceau.Maximum;
            }
    Y-at-il donc un moyen de concilier fluiditié de la lecture et déroulement du slider. Je précise que la méthode ControleLecture.lire() ne fait qu'appelet de manière transparente Audio.Play(), donc le problème ne peut résider là.

  5. #5
    Membre Expert
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    2 210
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 210
    Par défaut
    Salut,

    Citation Envoyé par Herwin78800
    La méthode BeginInvoke du Dispatcher prend en paramètre (DispatcherPriority, Delegate) et non pas l'inverse.
    http://msdn.microsoft.com/en-us/library/ms591206.aspx
    Tu ne dois pas avoir la SP1 . Au bas de cette page, on peut lire dans la partie "Change History" que des ajouts ont été fait concernant les méthodes BeginInvoke et Invoke (et ceci depuis la SP1) :
    http://msdn.microsoft.com/en-us/libr...ispatcher.aspx

    Après est-ce la raison de ton problème, je ne sais pas
    Moi j'ai testé avec des sons de 2 à 3 minutes et je n'ai soulevé aucun problème.

  6. #6
    Membre confirmé
    Inscrit en
    Novembre 2006
    Messages
    79
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Novembre 2006
    Messages : 79
    Par défaut Ok - Je vérifie ça et je reviens.
    Je vérifie ça et je reviens.
    Merci

Discussions similaires

  1. Réponses: 7
    Dernier message: 27/12/2006, 17h54
  2. Mise à jour d'une table avec une autre
    Par Lucien dans le forum SQL
    Réponses: 2
    Dernier message: 20/04/2006, 10h46
  3. [DOM4J] Mise à jour des docs xml avec dom4j
    Par kodo dans le forum Format d'échange (XML, JSON...)
    Réponses: 3
    Dernier message: 06/04/2006, 21h48
  4. Mise à jour dans un formulaire avec condition
    Par Bourni dans le forum Access
    Réponses: 4
    Dernier message: 06/03/2006, 22h13
  5. Mise à jour d'une table avec un fichier csv
    Par blackangel dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 26/05/2005, 14h46

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