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 Forms Discussion :

Positionner des boutons dynamiquement en fonction de la résolution


Sujet :

Windows Forms

  1. #1
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut Positionner des boutons dynamiquement en fonction de la résolution
    Bonjour,

    Dans un futur projet, je vais devoir afficher un plan d'étage sur lequel auront été définis des boutons à des endroits bien spécifiques.

    Pour que l'utilisateur place les boutons lui-même pendant le runtime, pas de problème.

    Par contre, je m'interroge sur la meilleure manière de stocker cela dans la DB pour pouvoir ré-afficher ces boutons au même endroit à la prochaine utilisation. C'est la première fois que je fais ce genre de chose alors je cherche conseils pour faire cela de la meilleure manière possible.

    Au premier abord, je me suis dit qu'il me suffisait stocker les coordonnées X (Left) et Y (Top) des boutons. Puis j'ai réalisé que ces coordonnées allaient changer en fonction de la résolution de l'écran de l'utilisateur. J'envisage actuellement de stocker le rapport entre le bord de l'écran et la hauteur/largeur totale.

    J'ai cependant l'impression qu'il y a quelque chose de bancale à cette solution.

    Comment feriez-vous ?
    Kropernic

  2. #2
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Personne n'a de conseils à donner à ce sujet ?
    Kropernic

  3. #3
    Membre expert


    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2006
    Messages : 970
    Points : 3 304
    Points
    3 304
    Par défaut
    En fait je pense que tu vas devoir faire un calcul en fonction de la résolution de ton écran qui peux effectivement changer d'un pc à l'autre.

    Ce lien pourrait peut-être être un début de solution, mais je chercherais un peu de mon coté demain si j'ai le temps, car la question m’intéresse.
    Articles sur les technologies .NET

    Une réponse vous a aidé ? utilisez le bouton

    Votre problème est résolu ? utilisez le bouton

  4. #4
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 441
    Points
    4 441
    Par défaut
    bonjour kropernic

    Si c'est une image de plan,
    1/ HotSpot :
    -un class HotSpot avec props x,y,id,description(label du bouton)..
    -un list<HotSpot>

    1/Control PictureBox dont
    -tu surveille constemment le SizeModechanged pour le garder à Normal
    (ca evite les distorsions)
    -Un ToolTip qui dans Pict_MouseMove indique les coords ou l'user veut placer le bouton et l'invite à clicker....
    -dans Pict_MouseClick,tu fais beaucoup de choses simples :
    =>tu recuperes les coords x,y (en SizeMode.Normal elle corressponde à celle des pixels image)
    =>tu droppe un bouton et tu lui assignes les x,y comme location....
    =>tu cree le new hotpot ("mappe" au bouton cree)en renseignant ses props =>tu l'ajoutes au List<HotSpot>

    3/en quittant tu serialize le list<hotspot> associe à l'image
    4/en lecture on deserialize le list<hotspot> et on peut recreer les boutons ou controls grace au list <HotSpot> ...

    Si le PictureBox est Custom,le list<HotSpot> et le Tooltip deviennent des props ...

    La surveillance du SizeMode necessitera un boolean qui si il est à true permet de passer normalement dans MouseClick(ajout de bouton et de hotspot) sinon exit

    Cela permet de garder une image à sa taille normale donc "dpi dependant" car gdi+ rectifie en sous main les tailles d'image pour eviter les distorsions...
    Mais heureusement nos hotspots suivent les coord pixels...
    Le SizeMode.Normal permet ainsi d'eviter les rescaling que tu as appeles une solution bancale à juste titre...
    Il reste un autre probleme ,s'il s'agit d'images de grandes dimmensions qui ne tiennent dans le PictureBox ,et vu qu'il n'est scrollable c'est de l'enveloppez dans un eventuel panel scrollable....

    bon code....

  5. #5
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Hello,

    Ca m'a l'air intéressant tout ça (j'ai été checker HotSpot sur le net).

    Par contre, tu parles d'utiliser des HotSpots ET des Buttons. De ce que j'ai lu sur le net, un HotSpot agit déjà plus ou moins comme un bouton. Ca ferait double emploi non ?

    En plus, qu'est-ce qui m'empêche de mémoriser les coordonnées des boutons placés sur le plan plutôt que de mémoriser celle des hotspots ?

    Mais reste malgré le problème de l'image qui, de fait, est vraiment plus grande que la taille de la picturebox (même en full screen sur un 21'').

    J'avais pensé comme tu le suggères à un panel scrollable qui contiendrait la picturebox avec l'image en taille normale mais ce sera refusé car pas assez user friendly (scroller dans un image, c'est difficile pour eux).

    J'ai donc placé l'image (que j'ai en fait mis en backgroundimage au cas où je voudrais afficher des trucs en plus par dessus) en mode zoom. Ce qui évite également les distorsions mais qui change la taille au moindre changement de la fenêtre.

    Je tente actuellement de récupérer la taille de l'image affichée. Le contrôle ne renvoyant malheureusement que la taille réelle de l'image, je me bats donc avec des calculs de proportion.
    Kropernic

  6. #6
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Bon, il a été décidé que l'écran avec cette histoire de bouton sur une image serait toujours en WindowState = Maximized.

    Dois-je m'attendre à des soucis de positionnement lorsqu'un user Y ouvrira le plan sur lequel un user X aura sauver un bouton ?
    N.B. : les deux users peuvent avoir des écrans et résolutions différentes.
    Kropernic

  7. #7
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Bon, je n'ai pas encore testé sur un écran différent du mien pour voir si les boutons restent bien à la même place mais j'ai déjà un comportement étrange que j'ai du mal à comprendre.

    Lors du load de ma form, j'affiche dans un DGV (DataGridView) les différents plans d'étage disponible et, lors de la sélection d'un plan, j'affiche le plan ainsi que les bontons qui ont été défini précédemment par l'utilisateur.

    Voici le code de l'event :
    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
        Private Sub dgvMap_RowEnter(sender As System.Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvMap.RowEnter
            pbMap.Controls.Clear()
            map = maps.GetFloorById(CByte(dgvMap.Rows(e.RowIndex).Cells("dgvcId").Value))
            pbMap.BackgroundImage = Image.FromFile(map.DTO.Map)
            pbMap.BackgroundImageLayout = ImageLayout.Zoom
            If map.DTO.Active Then
                pbMap.BackColor = Color.LightGreen
            Else
                pbMap.BackColor = Color.Red
            End If
            areas = ANTI_MALI_BLL.Areas.FetchAreasByFloor(map.DTO.Id)
            For Each area As ANTI_MALI_DTO.Area In areas.DTO
                CreateButton(area, True)
            Next
        End Sub
    Et la procédure CreateButton :
    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
        Private Sub CreateButton(area As ANTI_MALI_DTO.Area, enableDragMove As Boolean)
            Dim btn As New Button
            btn.Text = area.Name
            btn.Name = area.Name
            btn.Parent = pbMap
            Dim diffx, diffy As Integer
            Dim imgsize As Size = GetImageSize(pbMap)
            diffx = pbMap.ClientSize.Width - imgsize.Width
            diffy = pbMap.ClientSize.Height - imgsize.Height
            btn.Left = CInt(Math.Floor(imgsize.Width * area.X)) + diffx \ 2
            btn.Top = CInt(Math.Floor(imgsize.Height * area.Y)) + diffy \ 2
            btn.BackColor = Color.FromKnownColor(KnownColor.Control)
            btn.Width = ltbName.CreateGraphics.MeasureString(area.Name, New Font("verdana", 14, FontStyle.Regular, GraphicsUnit.Pixel)).ToSize.Width + 7
            btn.Padding = New Padding(0)
            btn.BringToFront()
            btn.EnableDragMove(enableDragMove)
        End Sub
    Lors du load, la première ligne du DGV est automatiquement sélectionnée (à l'affectation de la propriété DataSource j'imagine) et déclenche donc l'évènement.

    Mais à ce moment-là, pour une raison que j'ignore, la largeur de la PictubreBox (pbMap dans le code) est trop/plus grande et les boutons sont donc décalé sur la droite de quelques dizaines de pixels.

    Une fois la form chargée, si je change manuellement de ligne, les boutons sont bien affichés au même endroit.

    En pas à pas, voici les valeurs que j'ai pour la largeur de pbMap :

    • lors du load : 1565
    • après : 1431

    Pas de souci avec la hauteur par contre.


    Et voici l'appel pour cette form :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
        Private Sub llblArea_LinkClicked(sender As System.Object, e As System.Windows.Forms.LinkLabelLinkClickedEventArgs) Handles llblArea.LinkClicked
            Dim frm As frmArea = frmArea.Instance
            frm.MdiParent = Me.MdiParent
            frm.Text = store.DTO.Code & " - " & areas
            frm.Dock = DockStyle.Fill
            frm.Show()
            frm.Focus()
        End Sub
    J'avais envisagé la possibilité soient créés avant que le dockstyle de la form ne s'applique mais alors, la picturebox serait petite pendant le load et non l'inverse.



    Auriez-vous une idée du pourquoi du changement de largeur ?
    Kropernic

  8. #8
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Je vais clore cette discussion car le positionnement dynamique à l'air de bien fonctionner.

    Juste ce problème de largeur qui reste a régler pour lequel je préfère ouvrir une discussion spécifique sur le forum Langages\VB.

    Merci pour votre aide.
    Kropernic

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

Discussions similaires

  1. [Javascript Debutant]Comment positionner des boutons sur une Image?
    Par bylka dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 25/07/2007, 13h07
  2. Réponses: 3
    Dernier message: 16/05/2007, 10h03
  3. faire des boutons dynamiques
    Par gotcha007 dans le forum Flash
    Réponses: 4
    Dernier message: 21/01/2007, 11h21
  4. [VBA-E] bouton dynamique avec fonction
    Par ogenki dans le forum Macros et VBA Excel
    Réponses: 38
    Dernier message: 06/02/2006, 12h43
  5. [FLASH 8] gérer des boutons dynamiquement
    Par gregooo dans le forum Flash
    Réponses: 1
    Dernier message: 04/02/2006, 21h22

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