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] Pas de OnScroll sur un Slider ?


Sujet :

Windows Presentation Foundation

  1. #1
    Membre régulier Avatar de Thor Tillas
    Inscrit en
    Octobre 2006
    Messages
    113
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 113
    Points : 90
    Points
    90
    Par défaut [WPF] Pas de OnScroll sur un Slider ?
    Hello,

    Cela fait maintenant un bout de temps que je cherche le moyen de séparer les changement de valeur programmatique ou utilisateur d'un slider de mon application...

    J'ai un slider sur ma fenetre. je peux soit le modifier par code, soit le modifier par souris.
    Si je le modifie par souris je veux faire quelque chose pour mettre à jour mon état interne, si je le modifie par code, mon état interne n'a pas besoin d'être mis à jour.

    Pour l'instant, la mise à jour se fait lorsque l'on bouge avec la souris ou lorsque l'on bouge avec le code...

    Sur la trackbar de winform y avait un événement que l'on appelait Scroll qui le faisait très bien... mais la je trouve rien qui ressemble.

    Si quelqu'un a une idée... je l'accepte volontier...

    Merci déjà de m'avoir lu.


    P.S. un petit bout de code pour si jamais, même si je pense pas que ce soit très utile :

    ma window :
    (partie xaml)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    <Grid>
        <Slider x:Name="m_slider"
                Minimum="0.0"
                Maximum="1.0"
                Value="{Binding ElementName=m_timelineControl, Path=Position}">
          <Slider.ToolTip>
            <TextBlock Text="{Binding Path=Position}" />
          </Slider.ToolTip>
        </Slider>
      </Grid>
    (partie C#)
    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
     
         public static readonly DependencyProperty PositionProperty =
          DependencyProperty.Register(
            "Position",
            typeof(double),
            typeof(PreviewerTimelineControl),
            new FrameworkPropertyMetadata(new PropertyChangedCallback(OnPositionChanged)));
     
        public double Position
        {
          get { return (double)GetValue(PreviewerTimelineControl.PositionProperty); }
          set { SetValue(PreviewerTimelineControl.PositionProperty, (double)value); }
        }
     
        private static void OnPositionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
     
          if (?????)
          {
            // Je veux pas que ca entre la si ca vient de moveIt
            // je veux que ca entre la si ca vient d'une modification par souris...
          }
        }
        void moveIt(double newPosition)
        {
           Position = newPosition;
         }
    Au travail, il y a deux sortes de personnes. Ceux qui ont un pistolet chargé, et ceux qui creusent. Moi je creuse...

  2. #2
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Points : 19 434
    Points
    19 434
    Par défaut
    Pourquoi ne pas plutôt t'abonner à l'event Valuechanged de ton slider.

    Ensuite, dans le code, tu as un booleen qui passe à Vrai dans l'event MouseLeftButtonDown et qui passe à faux dans MouseLeftButtonUp.

    Dans le délégué correspondant à Valuechanged, tu regarde si le booleen est à vrai ou faux. S'il est à vrai, c'est que l'utilisateur utilise le slider pour changer la position

  3. #3
    Membre régulier Avatar de Thor Tillas
    Inscrit en
    Octobre 2006
    Messages
    113
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 113
    Points : 90
    Points
    90
    Par défaut
    C'était une bonne idée... mais aucun de ces deux événements est appelé sur le slider... on a beau cliquer comme des fous pas un seul événement MouseDown sur le slider...

    J'imagine que si on pouvait récupérer un lien sur le Thumbs tout serait réglé, mais comme j'ai pas encore trouver comment on peut récupérer le thumbs d'un slider... ben je suis bloqué.
    Au travail, il y a deux sortes de personnes. Ceux qui ont un pistolet chargé, et ceux qui creusent. Moi je creuse...

  4. #4
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Points : 19 434
    Points
    19 434
    Par défaut
    Citation Envoyé par Thor Tillas
    C'était une bonne idée... mais aucun de ces deux événements est appelé sur le slider... on a beau cliquer comme des fous pas un seul événement MouseDown sur le slider...
    Après un petit test, il s'agit des events PreviewMouseDown et PreviewMouseUp auxquels tu dois t'abonner pour que cela fonctionne

  5. #5
    Membre régulier Avatar de Thor Tillas
    Inscrit en
    Octobre 2006
    Messages
    113
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 113
    Points : 90
    Points
    90
    Par défaut
    ok... Merci pour ton aide thomas...

    Effectivement sur un slider les événements intéressants sont ceux précédé du mot clé Preview. Je ne sais pas si les autre événement sont généré et attrapé plus bas ou tout simplement pas générer du tout...

    Voici la réalisation que nous avons faite pour nos besoins :
    Le slider doit pouvoir se mettre à jour en fonction d'une propriété qui est rafraichi par un Model (la propriété Position dans mon code).
    Le slider doit pouvoir se mettre à jour en fonction des actions de la souris comme suit :
    - En cas de clic sur le slider (en dehors du thumb), le thumb se déplace à l'endroit de la souris et met la position du model à jour
    - En cas de clic sur le thumb, tant que le bouton est enfoncé, le thumb suis la souris et met à jour la position du model

    Nous avons donc récupérer les event PreviewMouseDown/Up et mis une variable booléen à jour.
    De plus dans l'évenement PreviewMouseDown, nous avons ajouter le fait que le GUI doit mettre à jour le modèle afin de permettre les clic sur le slider qui modifie le model (j'espère que je suis clair...)

    Pour déplacer le thumb lors du clic, il suffit de mettre la propriété IsMoveToPointEnabled à true... et WPF le fait tout seul.

    Pour que l'événement PreviewMouseDown soit appelé lors du clic, il faut forcer le slider à nous le forwarder en utilisant la méthode suivante : m_slider.AddHandler(...) sinon le slider mange l'event PreviewMouseDown et nous ne pouvont pas le récupérer... Même chose pour l'event PreviewMouseUp

    donc voici le code xaml:
    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
     
    <UserControl x:Class="TimelineControl"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 x:Name="m_timelineControl">
        <Grid>
        <Slider x:Name="m_slider"
                Minimum="0.0"
                Maximum="1.0"
                Value="{Binding ElementName=m_timelineControl, Path=Position}"
                IsMoveToPointEnabled="true">
          <Slider.ToolTip>
            <TextBlock Text="{Binding Path=Position}" />
          </Slider.ToolTip>
        </Slider>
      </Grid>
    </UserControl>
    Voici le backcode:
    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
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
     
    // quelque using ;-)
     
    namespace VideoControlLib
    {
      /// <summary>
      /// Interaction logic for TimelineControl.xaml
      /// </summary>
     
      public partial class TimelineControl :
        System.Windows.Controls.UserControl
      {
        //-------------------------------------------------------------------------
        #region Dependency properties
     
        public static readonly DependencyProperty PositionProperty =
          DependencyProperty.Register(
            "Position",
            typeof(double),
            typeof(TimelineControl),
            new FrameworkPropertyMetadata(new PropertyChangedCallback(OnPositionChanged)));
     
        public double Position
        {
          get { return (double)GetValue(TimelineControl.PositionProperty); }
          set { SetValue(TimelineControl.PositionProperty, (double)value); }
        }
     
        private static void OnPositionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
          TimelineControl ptc = (TimelineControl)d;
          if (ptc.m_isMouseDown)
          {
            // Seeking
     
            // la valeur du slider est un pourcentage, pour avoir la véritable valeur 
            // il faut la calculer
            double position = ptc.Position * ptc.m_model.Max;
     
            ptc.m_model.Position = position;
          }
        }
     
        #endregion
     
        public TimelineControl()
        {
          InitializeComponent();
     
          m_timer.Tick += new EventHandler(OnTickEvent);
          m_timer.Interval = TimeSpan.FromMilliseconds(50);
     
          // permet de récupérer les event meme si slider les a déjà traités
          m_slider.AddHandler(Slider.PreviewMouseDownEvent, new MouseButtonEventHandler(this.OnPreviewMouseDown), true);
          m_slider.AddHandler(Slider.PreviewMouseUpEvent, new MouseButtonEventHandler(this.OnPreviewMouseUp), true);
        }
     
        public void Initialize(IModel model)
        {
          m_model = model;
          DataContext = m_model;
     
          m_model.PropertyChanged +=
            new System.ComponentModel.PropertyChangedEventHandler(OnPropertyChanged);
     
        }
     
        //-------------------------------------------------------------------------
        #region Private callback
     
        private void OnTickEvent(object sender, EventArgs e)
        {
          if (m_timelineVM.PlayRangeOut.ReferenceTime == 0)
            return;
     
          // la position du slider est un pourcentage...
          //update position
          Position = m_model.Position / m_model.Max;
        }
     
        private void OnPropertyChanged(object sender,
          System.ComponentModel.PropertyChangedEventArgs e)
        {
          if (e.PropertyName == "IsPlayheadMoving")
          {
            if (m_model.IsPlayheadMoving)
            {
              m_timer.Start();
            }
            else
            {
              m_timer.Stop();
            }
          }
          if (e.PropertyName == "TransportState")
          {
             if( m_model.TransportState == TransportState.Stopped)
             {
                Position = 0.0;
              }
              else  if (m_model.TransportState == TransportState.Paused)
              {
                  // la position du slider est un pourcentage...
                  //update position
                  Position = m_model.Position / m_model.Max;
               }
           }
        }
     
           private void OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
          m_isMouseDown = true;
          // permet de placer le thumb lors du clic
          // la valeur du slider est un pourcentage, pour avoir la véritable valeur 
          // il faut la calculer
          double position = ptc.Position * ptc.m_model.Max;
          ptc.m_model.Position = position;
        }
     
        private void OnPreviewMouseUp(object sender, MouseButtonEventArgs e)
        {
          m_isMouseDown = false;
        }
     
        #endregion
     
        //-------------------------------------------------------------------------
        #region Private members
     
        private System.Windows.Threading.DispatcherTimer m_timer =
          new System.Windows.Threading.DispatcherTimer();
        private ViewModels.PlayerLib.ITimelineViewModel m_timelineVM;
        private ViewModels.PlayerLib.ITransportBasicViewModel m_transportVM;
        private bool m_isMouseDown = false;
     
        #endregion
      }
    }
    Voilà en espérant que ca puisse aider quelqu'un...
    Au travail, il y a deux sortes de personnes. Ceux qui ont un pistolet chargé, et ceux qui creusent. Moi je creuse...

  6. #6
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Points : 19 434
    Points
    19 434
    Par défaut
    Intéressant....

    Merci de partager tes découvertes avec nous

  7. #7
    Membre régulier Avatar de Thor Tillas
    Inscrit en
    Octobre 2006
    Messages
    113
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 113
    Points : 90
    Points
    90
    Par défaut
    de rien... ca me parait normal de poster les peu de choses que je découvre... je poste plus souvent pour poser des questions que pour y répondre alors quand je peux donner un 'tit truc je le fais volontier.
    Au travail, il y a deux sortes de personnes. Ceux qui ont un pistolet chargé, et ceux qui creusent. Moi je creuse...

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

Discussions similaires

  1. Evénements sur ActiveX, OK in WPF, pas en console
    Par Arnard dans le forum Framework .NET
    Réponses: 4
    Dernier message: 11/09/2012, 16h01
  2. pas de tips sur un slider
    Par DiverSIG dans le forum Ext JS / Sencha
    Réponses: 1
    Dernier message: 23/09/2011, 08h29
  3. WPF - Canvas.Children.Remove ne rafraichit pas le Canvas sur l'IHM
    Par Cecile5 dans le forum Windows Presentation Foundation
    Réponses: 2
    Dernier message: 21/11/2008, 10h40
  4. [CSS][IE]background d'affiche pas dans div sur IE
    Par Thomzz dans le forum Mise en page CSS
    Réponses: 7
    Dernier message: 21/09/2005, 23h32
  5. Detection d'un clic sur un Slider
    Par BNS dans le forum MFC
    Réponses: 2
    Dernier message: 21/06/2005, 10h22

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