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

VB.NET Discussion :

DatGridView + ScrollBar


Sujet :

VB.NET

  1. #1
    Membre émérite Avatar de methylene
    Profil pro
    Inscrit en
    Février 2010
    Messages
    659
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2010
    Messages : 659
    Par défaut DatGridView + ScrollBar
    Bonjour,

    J'aurais souhaité savoir si quelqu'un saurait comment mettre une scrollbar dans une "COLONNE" d'un datagridview, c'est à dire que la scrollbar soit propre à la colonne uniquement (scrollbar horizontale au passage).

    La colonne étant un contrôle ceci est faisable, mais bon, avant de chercher à faire compliqué je demande des fois qu'il y ait une solution assez simple.

    Peut-être avec une HScrollBar, mais je ne suis pas sûr que je puisse attribué comme Parent une colonne d'un DGV. Oui et en fait VS ne reconnaît pas cette fichu colonne comme un contrôle il fallait s'en douter.

    J'ai pensé à un 2ème dgv a colonne unique (pour récupérer la scrollbar horizontale, mais cela ne va pas m'aider à cause de la scrollbar verticale qui ne sera pas couplée avec celle du DGV principal) superposé au dessus de mon dgv principal. En gros deux grid séparées.

    Merci.

  2. #2
    Expert confirmé Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Par défaut
    Bonjour,

    On peut créér une VScrollBar qu'on positionnera au-dessus du DataGridViewHeader dont on aura augmenté la Height. On devra éventuellement repositionner cette VScrollBar sur les event ColumnDisplayIndexChanged (sur n'importe quelle colonne) et la redimensionner sur ColumnWidthChanged (sur la colonne contenant la ScrollBar).

    Pour tenir compte de la Value de la ScrollBar dans le rendu du DataGridView, on utilisera l'event CellPainting pour tracer le texte via un drawstring dont le x dépendra de la position la ScrollBar.

    Quand on bouge la Value de la VScrollBar, il faut redessiner la DataGridView avec (théoriquement) la méthode Refresh. Si le Refresh est inopérant (pas sur que tous les Refresh ou Repaint fassent bien leur boulot ), il faudra peut-être activer la method Paint() de chaque DataGridViewCell visible de la colonne. Pour déterminer les cellules visibles, on peut utiliser les propriétés FirstDisplayedCell, DisplayedRowCount et DisplayedColumnCount.

  3. #3
    Membre émérite Avatar de methylene
    Profil pro
    Inscrit en
    Février 2010
    Messages
    659
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2010
    Messages : 659
    Par défaut
    D'accord,

    Tout d'abord merci d'avoir répondu.

    Ceci dit, je vois l'idée mais cela m'a la'air assez compliqué, et je en suis pas sur que je vais y arriver tout seul comme un grand, mais bon je vais essayer.

    Au passage la colonne en question est de type Image et non text.

    Merci

  4. #4
    Membre émérite Avatar de methylene
    Profil pro
    Inscrit en
    Février 2010
    Messages
    659
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2010
    Messages : 659
    Par défaut
    En fait c'est une Hscrollbar et pas une Vscrollbar.

    Juste j'ajoute une image pour illustrer l'idée.

    Nom : scroll.PNG
Affichages : 143
Taille : 25,4 Ko

    Voilà mon tableau, avec la colonne en question, la scrollbar que l'on peut voir en dessous la colonne "Nombre de jours restants", avec des images dedans, et comme on peut voir mes images sont plus grandes que la taille de la cellule (et non je ne souhaite pas adapter l'image à la taille de la cellule).

    J'essaie encore de redessiner les cellules de ma colonne et de les lier à l'évènement de ma scrollbar mais j'y arrive pas .

  5. #5
    Expert confirmé Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Par défaut
    En fait c'est une Hscrollbar et pas une Vscrollbar
    Je pensais H et j'ai écrit V .

    Tu pourrais d'abord essayer sur une colonne Texte le méchanisme.

    Et ensuite, sur la colonne PictureBox, le CellPainting consisterait peut-être simplement à modifier le Location.x de la PictureBox contenue dans la cellule.

    Par rapport à ton image, mon idée était de déplacer la ScrollBar sur le RowHeader en haut (donc un scroll sur toute la colonne et pas seulement sur une cellule).

  6. #6
    Membre émérite Avatar de methylene
    Profil pro
    Inscrit en
    Février 2010
    Messages
    659
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2010
    Messages : 659
    Par défaut
    Par rapport à ton image, mon idée était de déplacer la ScrollBar sur le RowHeader en haut (donc un scroll sur toute la colonne et pas seulement sur une cellule).
    Oui oui je veux en effet un scroll sur toute la colonne.

    Par contre je veux la garder en bas, mais bon la position doit pas changer grand chose à mon avis.

  7. #7
    Expert confirmé Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Par défaut
    Par contre je veux la garder en bas, mais bon la position doit pas changer grand chose à mon avis.
    Raah, en bas de la cellule

    Tant pis, adaptons-nous: sur l'event RowEnter, on augmente la Height de la CurrrentRow pour pouvoir mettre la ScrollBar au-dessus du bas de la cellule (et on réinitialise la Height de la Row qui contenait la scrollbar avant le changement de row).

    Pour obtenir la position (x,y) de la cellule par rapport au haut du DataGridView , utiliser DataGridViewCell.GetCellDisplayRectangle.

  8. #8
    Membre émérite Avatar de methylene
    Profil pro
    Inscrit en
    Février 2010
    Messages
    659
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2010
    Messages : 659
    Par défaut
    Euh non non lol.

    Je pense que tu en me comprends pas bien :-). Pourtant sur la pièce jointe cela me paraîssait clair .

    Donc comme sur la PJ, sur ma dernière colonne en bas, (donc en dehors du DGV mais collée au DGV) j'ai une Hscrollbar. Et cette scrollbar doit donc pouvoir me faire défiler toute la colonne (et non pas une seule cellule). Comme je le disais la position de la scrollbar ne dois pas changer grand chose, du moment qu'elle est paramétrée sur la largeur de l'image la plus grande (pour le définlement) et sur le redessinage de la colonne (via les cellules), en fonction de la position du curseur.

    Qui plus est dans ton idée je suppose que tu définit la propriété "Parent" de la scrollbar au DGV, or moi je ne veux pas que ma scrollbar soit comprise dans le DGV (mais en dehors comme sur la PJ), donc "Parent" est sur le container de la DGV en l'occurrence.

    Et c'est cela que je n'arrive pas à mettre en place. Pour l'instant quand je bouge le curseur rien ne se passe ...

  9. #9
    Membre émérite Avatar de methylene
    Profil pro
    Inscrit en
    Février 2010
    Messages
    659
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2010
    Messages : 659
    Par défaut
    Bon ben voilà ma solution (après quelques bonnes heure de prise de tête avec le CellPainting, que je n'ai finalement pas utiliser), à savoir que cela marche bien car j'ai une image :

    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
        Private Sub scroll_Scroll(ByVal sender As Object, ByVal e As System.Windows.Forms.ScrollEventArgs) Handles scroll.Scroll
     
            'Redessine des images temporaires pour chaque ligne à partir de l'image principale
            Dim pos As Integer = scroll.Value
            Dim i As Integer = 0
            For Each row As DataGridViewRow In datagrid.Rows
     
                Dim btmp As New Bitmap(col3.Width, 22)
                Dim g As Graphics = Graphics.FromImage(btmp)
                g.DrawImage(imglist(i), New Rectangle(0, 0, col3.Width, 22), New Rectangle(pos, 0, col3.Width, 22), GraphicsUnit.Pixel)
                btmp.Save("C:\imgtemp\image" & i & ".png", ImageFormat.Png)
                Dim pts As New FileStream("C:\imgtemp\image" & i & ".png", FileMode.Open)
                row.Cells(2).Value = Drawing.Image.FromStream(pts)
                pts.Close()
                My.Computer.FileSystem.DeleteFile("C:\imgtemp\image" & i & ".png")
                i = i + 1
            Next
     
            End If
     
        End Sub
    En gros j'utilise mon image de base, et je redessine la partie correspondante au curseur.

    C'est relativement fluide, et ça fonctionne !

    Je rajoute ma source pour ceux qui voudraient regarder le projet (VS2008).

    Source : http://dl.free.fr/j4KXSiau3

    Bonne continuation et merci Graffito pour tes réponses.

  10. #10
    Expert confirmé Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Par défaut
    Bonjour,

    Est-ce qu'au final, on n'aurait pas pu faire plus simple (à condition que le nombre max de photos par ligne soit limité) :
    • en "figeant" les colonnes sans photo(propriété Frozen des DataGridViewRow),
    • en créant autant de colonnes que le nombre max de photos par ligne,
    • en mettant une photo par cellule,
    • et ça marche tout seul avec la ScrollBar standard

  11. #11
    Membre émérite Avatar de methylene
    Profil pro
    Inscrit en
    Février 2010
    Messages
    659
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2010
    Messages : 659
    Par défaut
    Sachant que les images sont des barres générées par le programme (dessinée en GDI+), je dirais que non étant donné que les "photos" ne sont pas fixe.

    Ci-dessous la fonction qui génère mes barres de taille complètes (qui sont stockées dans un fichier temporaire que je détruis à la fermeture de l'application).

    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
            Dim f As Graphics = Graphics.FromImage(imgf)
            Dim pinceau As New Pen(Color.Black)
            Dim Grect As New Rectangle(0, 1, 10 * Largeur1, 16)
            Dim Prect As New Rectangle(0, 1, 10 * Largeur2, 16)
            Dim myBrush = New LinearGradientBrush(Grect, Color.FromKnownColor(KnownColor.LightGray), Color.FromKnownColor(KnownColor.Gray), LinearGradientMode.Vertical)
            Dim myBrushs = New LinearGradientBrush(Prect, Color.FromKnownColor(KnownColor.White), Color.FromKnownColor(KnownColor.Turquoise), LinearGradientMode.Vertical)
     
            f.FillRectangle(Brushes.Transparent, Grect)
            f.FillRectangle(myBrush, Grect)
            f.FillRectangle(myBrushs, Prect)
            f.DrawRectangle(pinceau, Grect)
     
            For j = 1 To Largeur1 - 1
     
                f.DrawLine(pinceau, 10 * j, 1, 10 * j, 16)
     
            Next
     
            Return imgf
    Dans l'exemple de ma source j'utilise une imglist remplie avec des photos de My.Ressources, car c'était juste un exemple "test" pour tester ma méthode.

    Mais dans mon programme je pointe directement vers les images en questions via leur chemin d'accès. En sachant que dans mon tableau il ya plein de lignes qui ne doivent pas contenir d'image (les lignes titres et les lignes non visible).

    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
        Private Sub scrolling_Scroll(ByVal sender As Object, ByVal e As System.Windows.Forms.ScrollEventArgs) Handles scrolling.Scroll
     
     
            'Redessine des images temporaires pour chaque ligne à partir de l'image principale
            Dim pos As Integer = scrolling.Value
            Dim i As Integer = 0
            Dim j As Integer = 0
            Dim strong As String
     
            For Each row As DataGridViewRow In Datagrid4.Rows
     
                If row.Cells(4).Value <> "" And row.Visible = True Then
     
                    strong = imglist(i)
                    Dim btmp As New Bitmap(Duree4.Width, 18)
                    Dim btmpbis As New Bitmap(strong)
                    Dim g As Graphics = Graphics.FromImage(btmp)
                    g.DrawImage(btmpbis, New Rectangle(1, 0, Duree4.Width, 18), New Rectangle(pos, 0, Duree4.Width, 18), GraphicsUnit.Pixel)
                    btmp.Save("C:\imgtemp\img" & i & ".png", ImageFormat.Png)
                    Dim pts As New FileStream("C:\imgtemp\img" & i & ".png", FileMode.Open)
                    row.Cells(7).Value = Drawing.Image.FromStream(pts)
                    pts.Close()
                    My.Computer.FileSystem.DeleteFile("C:\imgtemp\img" & i & ".png")
                    i = i + 1
     
                End If
                j = j + 1
     
            Next
     
        End Sub

    imglist étant cette fois une liste de string (chemin d'accès des images) remplie lorsque j'ai une ligne correspondant au critère pour générer une image, via le sub suivant :

    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
        Public Sub AddBar()
     
            Dim i As Integer = 0
            Dim nbjourtot As Integer
            Dim nbjour As Single
            Dim p As Integer = 0
     
            For Each row As DataGridViewRow In Datagrid4.Rows
     
                Datagrid4.Rows(0).Cells(0).Selected = True
     
                If row.Cells(3).Value Is System.DBNull.Value Then
     
                    row.Cells(0).Style.Font = New System.Drawing.Font("Microsoft Sans Serif", 9.0!, System.Drawing.FontStyle.Bold)
                    row.Cells(1).Style.Font = New System.Drawing.Font("Microsoft Sans Serif", 9.0!, System.Drawing.FontStyle.Bold)
                    row.Cells(7).Value = My.Resources.vide
     
                ElseIf row.Cells(3).Value <= 0 Then
     
                    row.Visible = False
     
                ElseIf Round(TableActivity.rows(i).item(23)) < 1 Then
     
                    nbjourtot = TableActivity.rows(i).item(6)
                    nbjour = 1
                    imgf = New Bitmap(dimmax * 10 + 1, 18)
                    jourbar(nbjourtot, nbjour)
                    imgf.Save("C:\imgtemp\image" & w & "-" & i & ".png", ImageFormat.Png)
                    Datagrid4.Rows(i).Cells(7).Value = Drawing.Image.FromFile("C:\imgtemp\image" & w & "-" & i & ".png")
                    ReDim Preserve imglist(p)
                    imglist(p) = "C:\imgtemp\image" & w & "-" & i & ".png"
                    p = p + 1
                Else
     
                    nbjourtot = TableActivity.rows(i).item(6)
                    nbjour = Round(TableActivity.rows(i).item(23))
                    imgf = New Bitmap(dimmax * 10 + 1, 18)
                    jourbar(nbjourtot, nbjour)
                    imgf.Save("C:\imgtemp\image" & w & "-" & i & ".png", ImageFormat.Png)
                    Datagrid4.Rows(i).Cells(7).Value = Drawing.Image.FromFile("C:\imgtemp\image" & w & "-" & i & ".png")
                    ReDim Preserve imglist(p)
                    imglist(p) = "C:\imgtemp\image" & w & "-" & i & ".png"
                    p = p + 1
     
                End If
     
                i = i + 1
     
            Next
     
            w = w + 1
     
        End Sub

    D'où un code un peu plus complexe.

    Après l'idée d'une colonne par image (correspondant à une position du curseur de la Hscrollbar) que l'on viendrait cacher / afficher en fonction du curseur, est une bonne idée, surement plus fluide que celle que je retiens, mais pour ce faire il faut des images de "base" en dur, ce qui n'est pas mon cas.

    J'ajouterais que hors contexte ce n'est pas évident à comprendre.

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

Discussions similaires

  1. [Listbox] ScrollBar Horizontal
    Par haleem dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 20/04/2005, 07h53
  2. [FLASH MX2004] Personnaliser les scrollbars
    Par stephane eyskens dans le forum Flash
    Réponses: 10
    Dernier message: 09/10/2003, 12h53
  3. [VB6] [Scrollbar] Valeur maximale supérieure à 32750
    Par néo333 dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 11/12/2002, 10h24
  4. [VB6][Formulaire]Appliquer un Scrollbar a une Form
    Par Boil dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 09/11/2002, 03h51
  5. [visuel]ScrollBar et StatusBar
    Par psl dans le forum Composants VCL
    Réponses: 2
    Dernier message: 24/08/2002, 21h28

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