Récupérer les valeurs d'AutoScrollPosition quand un scroll est terminé //C#

Signaler
Messages postés
55
Date d'inscription
mardi 21 mai 2019
Statut
Membre
Dernière intervention
16 février 2020
-
Whismeril
Messages postés
14239
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
17 février 2020
-
Yo.

J'ai un AutoScroll sur mon form et j'aimerais récupérer les valeurs d'AutoScrollPosition quand un scroll est terminé, pour l'utiliser.

Dans l'ordre ça ferait :
- Je scroll avec la molette.
- ça détecte que j'ai scroll -ou- ça détecte qu'un scroll est terminé
- ça prend les valeurs d'AutoScrollPosition

Scroller avec la molette ça va je peux faire, pas de problème, je met mon doigt sur la molette, j'exerce une petite pression sur la molette, je plis le milieu et le devant du doigt, je reviens à la position précédente, pif, paf, ça fonctionne, c'est tout à fait fonctionnel de ce côté.

Prendre les valeurs d'AutoScrollPosition c'est aussi opérationnel :

        Point MagnifiquePoint = AutoScrollPosition;


Mais détecter que j'ai scrollé ou qu'un scroll est terminé, ça, aled, pour la première possibilité j'ai tenté de faire :

        private void mainForm_Load(object sender, EventArgs e)
        {
            this.Scroll += new ScrollEventHandler(MainForm_Scroll);    
        }

        private void MainForm_Scroll(object sender, ScrollEventArgs e)
        {
            Point MagnifiquePoint = AutoScrollPosition;
        }


ça fonctionne mais pas quand je scroll avec la molette. Embêtant...

Du coup j'ai cherché pour détecter quand les valeurs d'AutoScrollPosition changent, j'ai trouvé : ScrollBar.ValueChanged (https://docs.microsoft.com/fr-fr/dotnet/api/system.windows.forms.scrollbar.valuechanged?view=netframework-4.8) mais je n'arrive pas à récupérer la ScrollBar de l'AutoScroll...

Je présume que c'est un truc du genre :

        private void mainForm_Load(object sender, EventArgs e)
        {
            VScrollBar VTropBelleScrollBar = /*La VScrollBar de l'AutoScroll*/;
            VTropBelleScrollBar.ValueChanged += new EventHandler(MainForm_Scroll);
            HScrollBar HTropBelleScrollBar = /*La HScrollBar de l'AutoScroll*/;
            HTropBelleScrollBar.ValueChanged += new EventHandler(MainForm_Scroll);
        }

        private void MainForm_Scroll(object sender, EventArgs e)
        {
            Point MagnifiquePoint = AutoScrollPosition;
        }


Maiiiis... Je ne sais pas ce qu'il faut mettre à la place des commentaires.

Après, il faut aussi détecter quand le scroll est terminé, parce que sinon, "MagnifiquePoint" vaudra la position précédente de l'AutoScroll, et c'est pas ce que je veux. Je sais pas comment faire. Aled

11 réponses

Messages postés
14239
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
17 février 2020
454
Bonjour

je viens de tester et oui, étonnement c'est vrai.

J'ai repris le code que je t'avais fait la dernière fois, en supposant qu'il s'agit du même projet.
Il faut que tu interceptes le MouseWheel du panel
        public Form1()
        {
            InitializeComponent();

            this.Scroll += Form1_Scroll;
            panel1.MouseWheel += Panel1_MouseWheel;
        }

        Point test;
        private void Form1_Scroll(object sender, ScrollEventArgs e)
        {
            test = this.AutoScrollPosition;
        }

        private void Panel1_MouseWheel(object sender, MouseEventArgs e)
        {
            test = this.AutoScrollPosition;
        }

Messages postés
55
Date d'inscription
mardi 21 mai 2019
Statut
Membre
Dernière intervention
16 février 2020
6
Ah oui, MouseWheel, ça marche, merci.

Alors... ça fonctionne mais du coup y a ce problème de : ça donne la valeur au moment où on scroll et non à la fin du scroll.

J'ai donc testé avec un timer :
- Je scroll
- ça déclanche le timer
- Au bout de 3 secondes ça prend la valeur d'AutoScrollPosition
- ça marche, je peux l'utiliser

Mais, SURPRISE, quand.... AH attend ! En fait, c'est le MessageBox qui m'emmerdait, ah bah yes, en fait, je vérifiais si ça marchait grâce à un :

MessageBox.Show(" " +  monPointQuiVauxAutoScrollPosition);


Et quand je la faisais disparaitre avec entré ou en cliquant sur OK et bah ça me remettait en haut... Du coup ça fonctionne mais avec un timer c'est sujet à pas mal d'erreurs je pense...
L'idéal serait de détecter quand je scroll et quand je scroll plus, une sorte de ScrollUp comme le MouseUp.

En sachant que tout ça, je le fais juste pour pouvoir avoir un Point dans mon UserControl qui vaux AutoScrollPosition de mon mainForm en la passant par monUserControl_Load (parce que je sais pas comment faire autrement), j'aurais peut-être dû commencer par cette question, "Comment on fait pour avoir l'AutoScrollPosition de mon mainForm dans monUserControl ?"
Messages postés
14239
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
17 février 2020
454
Pour n'avoir que la valeur finale, là je ne sais pas, je vais chercher.
Pour avoir la valeur dans ton contrôle, y'a plusieurs options.
Tu peux appliquer toutes celles de ce tuto https://codes-sources.commentcamarche.net/faq/11107-interactions-entre-form-en-net-c-et-vb-net

Et en plus, comme c'est un contrôle, tu peux lui donner une propriété ou une méthode avec lesquelles tu interagis depuis le code du formulaire. C'est aussi possible avec les form, mais déconseillé, donc je ne l'avais pas mis dans le tuto.
Whismeril
Messages postés
14239
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
17 février 2020
454
J'ai rien trouvé de spécifique, et comme je suis sur Mac avec une virtual box, y'a des évènements de souris dont je ne suis pas sûr (y'a pas de roue sur une souris Mac, la surface agit comme un pad).

Donc, j'ai aussi joué avec un timer et ça marche bien.
J'ai mis 500ms, mais je pense qu'on doit pouvoir faire plus court, 250 ms voire moins.
J'ai mis un label pour afficher le résultat à la fin
        Timer timer = new Timer { Interval = 500 };
        public Form1()
        {
            InitializeComponent();

            this.Scroll += Form1_Scroll;
            panel1.MouseWheel += Panel1_MouseWheel;

            timer.Tick += Timer_Tick;
            label1.Text = "rien d'affiché";
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            test = this.AutoScrollPosition;
            label1.Text = test.ToString();
        }

        Point test;
        private void Form1_Scroll(object sender, ScrollEventArgs e)
        {
            timer.Stop();//le truc c'est de redémarrer le décompte tant que ça bouge
            timer.Start();
        }

        private void Panel1_MouseWheel(object sender, MouseEventArgs e)
        {
            timer.Stop();
            timer.Start();
        }
Messages postés
55
Date d'inscription
mardi 21 mai 2019
Statut
Membre
Dernière intervention
16 février 2020
6
Alors alooors, j'ai réussi à faire ce que je voulais. Pour la récupération de l'AutoScrollPosition de mon form j'y suis allé comme une bourrine, je l'enregistre directement dans une base de données à la fin du timer et je récupère les données dans monUserControl, hihihi

Mais il y a toujours ce problème de timer qui est sujet à des erreurs, ça pousse à devoir attendre (3 secondes) quand c'est de courts scrolls et devoir faire un scroll haut et bas pour être sûr qu'il ait bien récupéré les bonnes valeurs (j'ai eu une erreur dans la suite de mon programme parce que je suis allé trop vite ou quelque chose comme ça et les valeurs n'étaient pas bonne)

Tout ce fouillis uniquement parce que je n'arrive pas à prendre la position, non pas par rapport à mon écran, mais par rapport à où je suis dans mon form. J'ai cherché, j'ai trouvé "PointToClient()" mais ça ne marche pas du tout, la position de tout en bas de mon écran, par exemple, est toujours égal la position de tout en bas de mon écran après un scroll vers le bas (enfin, égal, pas vraiment, parce qu'il y a même un décalage) donc je comprends pas ce que fait ce truc.

Du coup voilà, si tu, ou quelqu'un d'autre, trouves un moyen pour "Récupérer les valeurs d'AutoScrollPosition quand un scroll est terminé" ce serait bien, je vais avancer dans mon appli, vu que malgré tout, ça marche, et je reviendrai sur ce problème. Après si quelqu'un sait comment "prendre la position, non pas par rapport à mon écran, mais par rapport à où je suis dans mon form" ça règle le problème. (merci @Whismeril )
Messages postés
14239
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
17 février 2020
454
Du coup voilà, si tu, ou quelqu'un d'autre, trouves un moyen pour "Récupérer les valeurs d'AutoScrollPosition quand un scroll est terminé" ce serait bien


As tu au moins essayé ce que je t'ai proposé?

Après si quelqu'un sait comment "prendre la position, non pas par rapport à mon écran, mais par rapport à où je suis dans mon form" ça règle le problème.

Dans n'importe quel évènement de souris, la position est par rapport au formulaire
Par exemple
        private void Panel1_MouseMove1(object sender, MouseEventArgs e)
        {
            this.Text = e.Location.ToString();
        }


Messages postés
55
Date d'inscription
mardi 21 mai 2019
Statut
Membre
Dernière intervention
16 février 2020
6
"As tu au moins essayé ce que je t'ai proposé? "

AH, en fait j'ai survolé le code et j'avais compris que c'était la même chose que moi, j'avais pas compris que tu proposais ça comme solution, bref, ouais, ça fonctionne bien, même si utiliser un timer me dérange un peu, ça fait pas propre, un peu comme si t'accrochais un truc au mur avec du scotch, un ScrollUp serait mieux. Je le rajoute dans les améliorations à faire.

"Dans n'importe quel évènement de souris, la position est par rapport au formulaire "

Bah... quand je déplace mon userControl, que j'enregistre sa position dans ma base de données, là il s'affiche bien à l'endroit voulu, mais quand je quitte l'appli' et que je la redémarre, l'userControl se retrouve chargé tout en haut, parce que ce qui est enregistré dans la base de données c'est pas les coordonnées par rapport à mon form, mais par rapport à mon écran.

Allez, un p'tit dessin pour mieux comprendre ce que je dis :



Voilà ce qui se passe, et ce que je veux c'est que le point marron soit au même endroit que le point vert et ce n'est pas ce qui se passe si je ne rajoute pas les valeurs d'AutoScrollPosition.
Là tout est bon en rajoutant les valeurs d'AutoScrollPosition, mais si quelque chose pouvais m'éviter d'utiliser autant de ligne de code juste pour faire l'ajustement, ce serait cool, en une petite méthode faire tout ça, tic tac bim.

Bon, du coup, j'estime que ce problème est résolu, mais je laisse quand même le post comme non résolu, parce que je veux mon ScrollUp, si quelqu'un passe par là ! Et si t'as d'autres solutions à me proposer..

(j'ai un autre problème après, bientôt un nouveau post, peut-être)
Messages postés
14239
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
17 février 2020
454
Alors, le truc c'est que je ne vois pas trop le rapport entre l'autoscroll et la position de ton contrôle. Pour moi, ce serait plutôt les propriétés Top et Left, ou éventuellement la propriété Location. Je ne fais plus de winform depuis un moment....

Peux tu poster le code qui enregistre la position dans la bdd et celui qui replace le contrôle au chargement.
Messages postés
55
Date d'inscription
mardi 21 mai 2019
Statut
Membre
Dernière intervention
16 février 2020
6
Parce que La Position que j'enregistre + AutoScrollPosition = Point Vert

Alors, j'ai pas trop envie de mettre mon code, en plus j'utilise pas mal de fois Location, Cursor.Position, etc.. etc... Trop long. Mais je pense que c'est parce que j'utilise Cursor.Position, qui doit être par rapport à l'écran. Genre :

Location = Cursor.Position;


Si c'est le cas, il faudrait avoir : Cursor.PositionOnTheForm
Messages postés
14239
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
17 février 2020
454
Si tu ne montres pas ton code, y'a peu de chance que je puisse t'aider efficacement.

Mais quoiqu'il en soit, pour moi c'est pas l'objet Cursor qu'il faut utiliser mais les évènements de souris (MouseMove, MouseDown etc....)
Pearusdoancaia
Messages postés
55
Date d'inscription
mardi 21 mai 2019
Statut
Membre
Dernière intervention
16 février 2020
6
Ouip, je sais, si je trouve le temps je ferrai une synthèse de mon code pour ce que tu me demande, mais je crois bien que c'est ce que je viens de dire. Dans ce cas je suis obligé de faire comme je fais parce que c'est indispensable que mon UserControl se charge à position de ma souris.
Messages postés
14239
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
17 février 2020
454
Ben oui justement, ces événements donne la position de la souris dans le repère du formulaire.
Pearusdoancaia
Messages postés
55
Date d'inscription
mardi 21 mai 2019
Statut
Membre
Dernière intervention
16 février 2020
6
Euh, je ne vois pas comment on peut enregistrer des variables grâce à des événements. ?_?

Yes, je reviendrai sur ce problème de position par rapport au form quand je reverrai tout mon code, parce que c'est un peu le bordel, je créerai sûrement un post dédié à ce problème si je trouve pas tout seul. (je laisse quand même ce post en non résolu pour l'histoire de "ScrollUp")
Messages postés
14239
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
17 février 2020
454
Quand tu abonnes une méthode à un évènement de contrôle Microsoft (et la majeur partie des autres objets aussi), la signature est toujours de ce genre
void NonDuControle_Evenement(object sender, EventArgs e)

La variable e peut être de n'importe quel type hérité de EventArgs

sender contient le contrôle (ou l'objet) qui généré l'évènement casté au type object, et e contient les informations utiles liés à l'évènement.

Dans le cas d'évènements de souris (MouseDown, MouseUp etc...) e est de type MouseEventArgs et contient les coordonnées de la souris dans le repère du formulaire.


Mais ça, je ne devrais pas avoir à te l'expliquer puisque cela fait parti des bases de C#.
Bases qu'il faudrait apprendre avant de se lancer à corps perdu dans son projet, afin d'éviter de tourner en rond sur un forum des jours durants.

Par exemple à coup de 2 à 3 heures par jour, tu peux suivre ce cours http://tahe.developpez.com/dotnet/csharp/ en 3 à 4 jours.

Qu'en penses tu, pour t'économiser une discussion qui dure depuis 9 jours.....