locked
DataGridView et MouseMouse RRS feed

  • Question

  • Salut à tous.

     

    Je dois, lorsque la souris passe sur une courbe préalablement dessinée dans une zone graphique, afficher dans un DataGridView les valeur de cette courbe à cet endroit.

    J'ai donc un événement MouseMouve, défini sur ma zone graphique, qui calcule, en fonction de la position de la souris, les données à afficher dans mon DataGridView.

    A l'exécution, il se passe des choses bizarres.

     

    J'ai fait une petite application minimale qui met en évidence le problème.

     

    1. créez un DataGridView nommé "dgv" qui contient une seule colonne nommée "col".

    2. créez une zone graphique dont l'événement MouseMove contient le code suivant:

     

    Dim compteur, nouvelle_ligne As Integer

    Beep()

    dgv.Rows.Clear()

    For compteur = 0 To 20

    nouvelle_ligne = dgv.Rows.Add

    dgv.Rows.Item(nouvelle_ligne).Cells.Item("col").Value = compteur

    Next

     

    Sur mon PC, à l'exécution, l'application boucle sans fin.

    Si je remplace, par exemple, le MouseMove par un appel d'un Timer rapide, tout est normal.

    Très étrange...

     

    Avez-vous une idée?

     

    Alain.

     

    vendredi 1 août 2008 10:04

Réponses

Toutes les réponses

  • Bonjour,

      Il me semble que le mouseMove peut se produire un peut souvent... le moindre pixel et hop tu auras l'événement...

      Perso je ferai un truc du genre :

     

    Code Snippet

    bool EnCours = false;

    onMouseMove(..)

    {

      if (!EnCours)

      {

        EnCours = true;

       

        dgv.Rows.Clear()

        ....

       

        System.Threading.Thread.Sleep(50); //laisser une tite pause de 50 ms avant de traiter un autre mousemove

        EnCours = false;

      }

    }

     

     

    Bon tu "perdrais" des mousemove mais en même temps tu aurais tout de même un quasi instantané...

    Aprés une autre astuce pour gagner en perf mais la ca dépend de ton code : quand tu généres le graph tu pourrais générer en anticipation les données pour le datagrid associé ? Par exemple tu pourrais avoir une liste des points du graph avec pour chaque point les données ( Dictionnary<Point, List<DataRow>> maListe )

    Ainsi sur le mousemove tu n'aurais "plus qu'a" faire un petit :

    dgv.Rows.Clear()

    dgv.Rows.AddRange(maListe[coordMouse])

    (Attention c'est l'idée aprés faut voir les cast et ce que tu as en entrée du mousemove comme info...)

    Voila, en espérant t'avoir aidé,

             Stéphane

    vendredi 1 août 2008 11:11
  •  

    Salut Stéphane.

    Merci pour ta réponse.

     

    J'essayerai ta solution lundi à mon travail mais je ne pense pas que le problème soit que le MouseMove génère trop d'événement car j'ai fait le test en le remplacant par un Timer rapide et, là, mon DataGridView se met bien à jour et suit le rythme... d'ailleurs, si je fais très peu de déplacement avec ma souris - par exemple, si j'entre seulement de quelques points dans ma zone graphique puis que je ne bouge plus - mon application boucle de manière infinie malgré tout !!!

     

    Est ce que tu as le même problème que moi si tu exécutes le petit programme de mon premier message ?

     

    Bonne journée,

    Alain.

     

     

     

    samedi 2 août 2008 13:35
  •  

    Salut,

      Je testerai et te dirai ca demain! J'ai pas trop de VS sous la main (enfin si mais sur un PC un poil lent et vu l'heure et mon weekend j'suis pas motivé Wink )

      A+,

           Stéphane

    dimanche 3 août 2008 19:49
  • Salut,

      En effet c'est super étonnant !! J'ai cherché un peu sur le net et j'ai pas trouvé d'autres personnes parlant de ce genre de chose.....Un peu comme si l'événement étais appellé en boucle, vraiment surprennant!!!

      bref voila une petite solution pas propre mais qui a le mérite de marcher :

     

    Code Snippet

    Private Moving As Boolean = False 'Pour ‚viter les parcours simultann‚s

    Private LastPoint As Point = Nothing 'Pour check de mouvement

     

    Private Sub PictureBox1_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove

    Dim HasChange As Boolean

    If (Not Moving) Then

    Moving = True 'traitement du mousemove

     

    'Controle que la souris a vraiment boug‚

    If (LastPoint = Nothing) Then

    LastPoint = e.Location

    HasChange = True

    ElseIf ((LastPoint.X <> e.X) Or (LastPoint.Y <> e.Y)) Then

    LastPoint = e.Location

    HasChange = True

    Else

    HasChange = False

    End If

     

    'Si mouvement : on remplis le datagrid

    If (HasChange) Then

    Dim compteur, nouvelle_ligne As Integer

    DataGridView1.Rows.Clear()

    For compteur = e.Location.X To e.Location.X + 20

    nouvelle_ligne = DataGridView1.Rows.Add

    DataGridView1.Rows.Item(nouvelle_ligne).Cells.Item("col").Value = compteur

    Next

    End If

     

    'Forcer le dessin du datagrid

    Me.Refresh()


    'petite pause histoire de...

    System.Threading.Thread.Sleep(500)

     

    Moving = False 'fin du traitement

    End If

    End Sub

     

    Voila j'ai testé la ca marche bien mieux !

    Désolé pour la coloration du code je sais pas pourquoi le copié/collé de VB déconne Sad

    Si quelqu'un par hasard connais une solution plus clean je suis prenneur ! (déjà une explication du "bug" Wink )

     

    A+ & dis nous si ca tu t'en sors avec ca Big Smile

         Stéphane

     

    PS: j'ai fais le test rapide en C# et pareil!

    lundi 4 août 2008 13:17
  • Salut Stéphane.

     

    Merci pour ton aide.

    Je n'aurai pas le temps de tester ta solution aujourd'hui car j'ai fini ma journée de travail à 16h00 et je viens de découvrir ton message (15h26).

    Je teste demain.

     

    Encore merci !

     

    Peut-être faudrait-il informer Microsoft du bug ?

     

    A demain,

    Alain.

     

    lundi 4 août 2008 13:27
  •  Alain1024 A écrit:

    Peut-être faudrait-il informer Microsoft du bug ?

     

    Wink Je vais commencer par tester que c'est pas un bug, aussi bien ca s'explique et y'a une solution pour éviter ce truc (je pense que c'est un bug lol)

    Et aussi bien le SP1 de VS2008 corrige déjà ce problème (bien que ca vienne peut-être du framework....)

    Bref c'est super étonnant que personne n'ai déjà signalé ce truc.....

    Quelqu'un de MSDN France qui pourrais nous dire ? Big Smile

    ++,

         Stéphane

    lundi 4 août 2008 16:37
  • Es-ce que tu as regardé sur le site de Connect pour voir si le bug avait déjà été signalé.
    lundi 4 août 2008 17:40
  •  

    Salut,

      J'avais regardé vite fais avant mon post quand même Wink voici ce que j'ai trouvé mais sur "Visual Studio 2005 Service Pack 1 Beta" (enfin "Visual Studio .Net English") :

    https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=244426

      Je suppose qu'il y a une connexion pour le SP1 2008 mais sauf erreur je n'y ai pas accés Sad sniff Crying

      Tu sais si il y un site connect pour VS2008 ou pour le framework ?

     

      Par contre sur le forum US de msdn on trouve pas mal d'entrée qui parle de mousemove et je crois avoir un début d'explication en lisant un peu ces posts mais ca parait tordu : le fait de remplir le datagrid fait un "clignotement" de souris et donc redéclenche le mousemove....

    exemple :

    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=3024488&SiteID=1

    http://forums.msdn.microsoft.com/en-US/wpf/thread/a2bd4b5d-ea87-4bfc-8ad0-77a8578bb5b1/

    et d'autres....

     

      Chose marrante : ils présentent tous le même code que moi a 2/3 nuances prét Sad les boules j'fais comme les autres Tongue Tied (** humour **)

     

      ++,

             Stéphane

     

    lundi 4 août 2008 18:34
  • Stéphane,

     

    Le code que tu me proposes me convient bien.

    Je suis toujours étonné de voir la richesse des possibilités de .NET mais il y a aussi quelques étrangetés comme celle-ci.

     

    Bonne journée,

    Alain.

     

    mardi 5 août 2008 06:33