Magnetiser un Form pour accrochage UserControl [Résolu]

Signaler
Messages postés
372
Date d'inscription
vendredi 27 juillet 2007
Statut
Membre
Dernière intervention
22 juillet 2013
-
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
-
Bonjour ,
J'ai des 'UserControl' que j'ai crée et je les déplace sur le Formulaire (Form) avec la souris.
Je souhaite magnétiser donc créer un accrochage objet sur un form que sorte à pouvoir bien positionner les 'UserControl' correctement.

Comment puis je ''magnetiser le formulaires' ?
Existe t'il une propriété ? Dois je écrire un code ?

Merci de votre aide
Dedenet2

32 réponses

Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
225
Tu devrais trouver des exemples de ce genre de mécanisme dans de nombreux codes, notamment (exemple) pour jeu de Scrabble


________________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement vous dire ce qu'elle contient. Je n'interviendrai qu'en cas de nécessité de développ

Bonsoir,

Intéresse toi à la classe Rectangle et sa fonction Intersect.

Admettons que tu veuille placer ton contrôle dans un rectangle nommé A.

Nommons B le rectangle que représente ton contrôle en cours de déplacement.

Rectangle.Intersect(rect A, rect B) retourne un troisième rectangle (appelons le C) qui représente l'intersection de 2 autres.

En calculant les dimensions de C et en dessous de valeurs (width et height) que tu auras fixé à l'avance, tu pourras décider de donner à ton contrôle l'emplacement du rectangle A.

Voici un petit exemple non commenté puisque déjà expliqué ci-dessus.

Option Strict On
Public Class Form1
    Dim WithEvents Conteneur As New Panel With {.Bounds New Rectangle(0, 0, 202, 202), .Parent Me, .BackColor = Color.LightSteelBlue, .BorderStyle = BorderStyle.FixedSingle}
    Dim WithEvents Element As New PictureBox With {.Bounds New Rectangle(210, 80, 50, 50), .Parent Me, .BackColor = Color.Pink, .BorderStyle = BorderStyle.FixedSingle}

    Dim PointOrigine As Point
    Dim ListeRectangles As New List(Of Rectangle)
    Dim ListeRectanglesPoses As New List(Of Rectangle)

    Private Sub Element_MouseDown(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Element.MouseDown
        If e.Button = Windows.Forms.MouseButtons.Left Then
            PointOrigine = New Point(e.X + Me.Left + SystemInformation.BorderSize.Width, _
                                     e.Y + Me.Top + SystemInformation.CaptionHeight)
            Element.BackColor = Color.Pink
        End If
    End Sub

    Private Sub Element_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Element.MouseMove
        If e.Button = Windows.Forms.MouseButtons.Left Then
            DirectCast(sender, PictureBox).Location = Point.Subtract(Cursor.Position, New Size(PointOrigine))
        End If
    End Sub

    Private Sub Element_MouseUp(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Element.MouseUp
        For Each rect As Rectangle In ListeRectangles
            Dim RectInter As Rectangle = Rectangle.Intersect(Element.Bounds, rect)
            If RectInter.Width > 25 And RectInter.Height > 25 Then
                If Not ListeRectanglesPoses.Contains(rect) Then
                    Element.Bounds = New Rectangle(rect.Left + 1, rect.Top + 1, 51, 51)
                    ListeRectanglesPoses.Add(rect)
                    Exit For
                Else
                    Element.BackColor = Color.Red
                End If
            End If
        Next
    End Sub

    Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        Element.BringToFront()
        For y As Integer = 0 To 3
            For x As Integer = 0 To 3
                Dim MonRectangle As Rectangle = New Rectangle(x * 50, y * 50, 50, 50)
                ListeRectangles.Add(MonRectangle)
            Next
        Next
    End Sub

    Private Sub Conteneur_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Conteneur.Paint
        For Each rect As Rectangle In ListeRectangles
            If ListeRectanglesPoses.Contains(rect) Then
                e.Graphics.FillRectangle(Brushes.Gray, rect)
                e.Graphics.DrawRectangle(Pens.Blue, rect)
            Else
                e.Graphics.DrawRectangle(Pens.Blue, rect)
            End If
        Next
    End Sub
End Class
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
225
Bonjour,
Pas très clair !
Si tu ne veux plus qu'on puisse à nouveau déplacer :
Il suffit, me semble-t-il, de ne pas en permettre un second déplacement, non ?
L'utilisation d'une simple variable booléenne devrait alors suffire.

Si tu veux par contre forcer un "déposé" à un emplacement plus précis que le geste de l'utilisateur : un simple container fera l'affaire, de cette manière :
-- si le déposé se fait hors container : rien n'est déplacé (retour à la base, avec message)
--- si le contrôle déplacé "touche" le container choisi : on l'y ajuste automatiquement
________________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement vous dire ce qu'elle contient. Je n'interviendrai qu'en cas de nécessité de développ
Messages postés
372
Date d'inscription
vendredi 27 juillet 2007
Statut
Membre
Dernière intervention
22 juillet 2013
1
Bonsoir ,

Les controles que je déplace avec la souris font 100x100.
Comme dit ucfoutu , le formulaire sera quadrillé comme un scrabble avec des cases de taille 100x100 comme les controles. Dès que ce dernier
sera pratiquement positionné dans l'un des rectangles , le controle sera
attiré comme un aimant dans ce rectangle.

babana32 ,je vais me pencher sur cette fonction Intersect

Merci
Dedenet2
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
225
Dès que ce dernier sera pratiquement positionné dans l'un des rectangles , le controle sera attiré comme un aimant dans ce rectangle.

Fais attention à tes expression, dedenet32. Elle sont souvent, d'une certaine manière, le reflet d'une pensée insuffisamment organisée.
Ton "dès que" est à remplacer par "si, au déposé".
Imagine donc, avec ton "dès que", ce qui se passerait lorsque, pour atteindre une case, sur devrais en survoler une autre !!! ...

________________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement vous dire ce qu'elle contient. Je n'interviendrai qu'en cas de nécessité de développ
Messages postés
372
Date d'inscription
vendredi 27 juillet 2007
Statut
Membre
Dernière intervention
22 juillet 2013
1
Bonjour ,
C'est plutot dedenet2 et pas 32. Pas grave !

Je te comprends ucfoutu !
Le deplacement des controles se fait en restant appuyant sur le bouton gauche et
l'accrochage de l'objet dans la case ne pourra se faire qu'en relachant
le bouton.
Du coup , je pourrais survoler les cases sans souci.
Tu m'as cité comme exemple le scrabble et je n'ai rien trouvé.
Pourrais tu m'indiquer les sites où on peut trouver un exemple de code ?

Merci

Dedenet2

Bon je reviens sur ce sujet pour apporter des précisions.
Bien entendu, c'est une solution qui m'est personnelle, ça ne veut pas dire que ce soit la meilleure.
Le principe consiste à générer une grille de rectangles fictifs à l'aide de la classe Rectangle avec une boucle imbriquée For / Next en incrémentant 2 variables x (colonnes) et y (lignes).
Ces rectangles peuvent être ajoutés à une List(Of Rectangle) par exemple.
Lorsque ton contrôle en cours de déplacement survole un des rectangles de ta List(Of, (qu'on énumère dans l'événement MouseMove) on se sert de la fonction Intersect pour déterminer lequel des rectangles de la List(Of recoupe le mieux ton rectangle en cours de déplacement (largeur et hauteur les plus grandes pour le rectangle retourné par la fonction).
Lorsque ce fameux rectangle est repéré dans l'énumération, et l'utilisateur ayant relâché sa souris, (événement MouseUp) on force l'élément déplacé sur l'emplacement du rectangle repéré.

Notes complémentaires: le rectangle de l'élément en cours de déplacement est donné par sa propriété Bounds.
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
225
Bonjour, banana32,
Je n'ai pas voulu, dans l'incertitude (absence de précisions) aller plus loin, mais ===>>
Mon petit doigt me donne à penser que ce qu'il cherche en réalité à faire est d'insérer dans un cadre de destination, les uns à la suite des autres selon un ordre déterminé (en colonnes et rangs) des usercontrols qu'il fait "glisser" vers une espèce de "boîte à outils".
Cela serait encore plus simple : au "lacher" sur cette "boîte" : si le 1er : en haut et à gauche et déjà déterminer l'emplacement du suivant. Si le nième, le mettre à l'emplacement ainsi déterminé par le précédant et déterminer l'emplacement du suivant.
Mais rien ne dit que j'ai raison de supposer que tel est vraiment le but recherché.


________________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement vous dire ce qu'elle contient. Je n'interviendrai qu'en cas de nécessité de développ

@ucfoutu
C'est vrai que j'étais parti sur ton fameux 'scrabble'

Quoi qu'il en soit, le demandeur a surement déjà terminé depuis le temps...
Messages postés
372
Date d'inscription
vendredi 27 juillet 2007
Statut
Membre
Dernière intervention
22 juillet 2013
1
Bonsoir à vous 2 ,
Non, je n'ai pas ternimé. J'avance à petits pas en fonction du temps que je dispose. Mais je ne suis pas pressé.
J'étais partit plutôt sur des lignes fictives horizontales et verticales écartées de 100 étant donnée que les objets (usercontrols) que je déplace avec la souris font 100x100.
Le but est donc d'accrocher le coin Haut-Gauche de l'objet dès lors qu'il se rapproche d'une intersection de 2 lignes (1 Horizontale et 1 Verticale). Ce qui revient à un quadrillage fictif du formulaire.
Mais il faut aussi que je trouve le moyen d'éviter que 2 objets se positionne au même endroit.

L'assemblage de ces usercontroles qui vont représentées des symboles dans le dommaine électriques va représenté un synoptique.Ces usercontroles seront le plus souvent mis bout à bout horizontalement ou verticalement mais pas nécessairement !

Mais j'en suis pas encore là !
Banana32, il faut que je teste aussi tes solutions que je ne connais pas (intersect....)

Dedenet2
Messages postés
18
Date d'inscription
jeudi 12 février 2009
Statut
Membre
Dernière intervention
15 février 2013

bonjour
peut etre que si mon Form.Top est 112 alors on est sur la ligne 2
et si Form.left est aussi 112 on est colonne 2
donc Form.Top 101 et Form.Left 101
@+JP
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
225
________________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement vous dire ce qu'elle contient. Je n'interviendrai qu'en cas de nécessité de développ
Messages postés
372
Date d'inscription
vendredi 27 juillet 2007
Statut
Membre
Dernière intervention
22 juillet 2013
1
Désolé MJPMJMJP , je ne peux pas accepter cette réponse !!!
Bonne nuit
Messages postés
18
Date d'inscription
jeudi 12 février 2009
Statut
Membre
Dernière intervention
15 février 2013

bonjour
des lignes fictives horizontales et verticales écartées de 100 étant donnée que les objets (usercontrols) que je déplace avec la souris font 100x100
ok d'accord c'est simpliste...alors imagine ton ecran comme la bataille navale chaque navire est un composant dans une grille ou un tableau a 2 entrée(x,y) avec 0 pour vide et 1 pour utilisé et si on superpose un autre tableau avec (x,y)=volt ou ampere...et pourquoi pas un troisieme tableau (x,y)=entre boolean pour un branchement possible....

donc un point (x,y) est libre et est une entree true avec un voltage...
je branche mon composant qui occupe n point (x,y) plus libre mais avec 2 entrees (x,y) (ou sortie en volt...)

pour conclure un plan graphisme et des plans data ... il faut adapter le code au concept et pas l'inverse
@+JP
Messages postés
18
Date d'inscription
jeudi 12 février 2009
Statut
Membre
Dernière intervention
15 février 2013

bonjour
je viens de me relire et ca parait cool
je ne sais pas si vous etes dans le meme delire mais voila comment ca pourrait dégénérer

j'ai un control avec une image qui représente un trai de soudure de 4 points sur la grille
quand je glisse mon image un evenement parcour mon tableau(x,y)...s'il existe (x,y)=true alors un indicateur s'alume et si on pose... notre image se fixe (on peut ici envisager un direction et un encrage sur un point n2) on a maintenant une soudure (c'est la que ca degenere!!!) avec un form qui represente un testeur on pointe sur la soudure de 4 points (x,y) et la une des couches tableau(x,y)=volt indique a notre form un voltage de 12v...
pour ceuce qui n'on pas griller la peruque....
j'ai un control ... une résistance
je glisse je pose sur la soudure...mon testeur qui pointe sur l'autre point desortie de la résistance affiche un chiffre...
ce chiffre est issu de mon control résistance qui a effectué une opération a transmit le résulta a ma couche tableau(x,y) lors de la pose...

bon voila c'est promit j'arrete le chocolat
@+JP

Bonjour MJPMJPMJP,

Pour une simple résistance avec du continu tu t'en sortiras facilement.
Par contre ajoutes à ton circuit quelques condos, des transistors, des diodes etc...
Moins simple tout d'un coup hein ?

Et pourtant certains l'ont fait.
Il y a même une version limitée en composants pour l'essayer
Messages postés
18
Date d'inscription
jeudi 12 février 2009
Statut
Membre
Dernière intervention
15 février 2013

bonjour
non parceque chaque composant calcule sa propre sortie comme dans la realite
on peut meme utiliser le timer pour simuler une charge de condensateur
@+JP

J'ai beau chercher, je ne vois pas trop comment faire en connectant plusieurs composants entre eux et l'alimenter en 'live'. Mais si tu trouves une solution, ça m'intéresse.
Messages postés
18
Date d'inscription
jeudi 12 février 2009
Statut
Membre
Dernière intervention
15 février 2013

bonjour
fait un test sur excel sans graphisme
case1 volt
case2 element
case3 resultat
ensuite tout ce qui est a la sortie de case3 va subir son influance...

je connait pas du tout l'electronique mais ca peut pas etre autrement
chaque composant a sa propre formule magique qui est modifiée par la presence d'autre composant
a mon avis avant de prendre le fer a souder le mec il met tout (calcul) sur papier

a part ca c'est juste une idée...qui peut ou pas etre utile
pour presenter l'idée d'utiliser les tableau en superposition comme on utiliserait une DataBase avec sa Key et ses Champs

n'oublions pas au départ c'était juste pour positionner un composant
mais une vue globale meme flou c'est mieux

@+JP