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 :

Multi selection dans un datagridview


Sujet :

VB.NET

  1. #1
    Membre régulier
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    277
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Août 2010
    Messages : 277
    Points : 122
    Points
    122
    Par défaut Multi selection dans un datagridview
    Bonjour

    J'aimerais pouvoir sélectionner plusieurs lignes d'un datagridview sans avoir a appuyer sur le bouton control en même temps que je clique.

    La propriété du control est sur multiselect = vraie
    la propriété selection mode est sur fullrowselect

    Je cherche donc a intercepter l'appuie de la touche gauche de la sourie avant mon prog et la remplacer par un (ctrl + clik gauche)

    Premiere question: Est ce la bonne méthode?

    Pour faire ca j'ai crée un control personnalisé dont voici le code

    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
    Public Class DGV_Multiselect
        Inherits DataGridView
        Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
            MyBase.OnPaint(e)
     
            'Ajoutez ici votre code de dessin personnalisé
        End Sub
     
        <System.Security.Permissions.UIPermission( _
            System.Security.Permissions.SecurityAction.LinkDemand, _
            Window:=System.Security.Permissions.UIPermissionWindow.AllWindows)> _
        Protected Overrides Sub OnMouseClick(ByVal e As System.Windows.Forms.MouseEventArgs)
     
            If Windows.Forms.MouseButtons.Left Then
                SendKeys.Send("^{LButton}")
            Else
                MyBase.OnMouseClick(e)
            End If
        End Sub
     
     
    End Class
    Mais cela ne fonctionne pas avec cette instruction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SendKeys.Send("^{LButton}")
    Quelqu'un pourrait il m'aider a résoudre ce problème.

    Merci d'Avance
    Gilles

    Ps: le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SendKeys.Send("^(LButton)")
    plante carement l'ordi, alt+ctrl+sup pour le débloquer et sortir du débogage

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 753
    Points
    39 753
    Par défaut
    Tu peux faire quelque chose comme ça :

    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
    ...
     
    Private dgv As DataGridView
     
    Private Sub dgv_MouseDown(sender As Object, e As MouseEventArgs)
    	Dim hit = dgv.HitTest(e.X, e.Y)
    	If hit.Type = DataGridViewHitTestType.RowHeader AndAlso hit.RowIndex >= 0 Then
    		Dim selectedRows = dgv.SelectedRows.Cast(Of DataGridViewRow)().ToArray()
     
    		' Une fois que l'évènement sera traité, resélectionner les lignes qui
    		' étaient sélectionnées avant le click
    		dgv.BeginInvoke(New Action(Of DataGridViewRow())(AddressOf ReselectRows), DirectCast(selectedRows, Object))
    	End If
    End Sub
     
    Private Sub ReselectRows(rows As DataGridViewRow())
    	For Each row As var In rows
    		row.Selected = True
    	Next
    End Sub
     
     
    ...
    C'est pas très élégant, mais ça marche. Le principe est de laisser l'évènement MouseDown être traité normalement (et donc de sélectionner la ligne cliquée), mais de resélectionner juste après les lignes qui étaient déjà sélectionnées. C'est ce que fait BeginInvoke : ça met "en file d'attente" une action à exécuter quand les autres évènements seront traités.

  3. #3
    Membre régulier
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    277
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Août 2010
    Messages : 277
    Points : 122
    Points
    122
    Par défaut
    Bonsoir Tomlev et merci de m'avoir répondu

    A quelle classe correspond var?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    For Each row As var In rows

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 753
    Points
    39 753
    Par défaut
    En fait j'ai écrit le code en C#, et j'ai utilisé un convertisseur automatique pour le passer en VB... mais le convertisseur a quelques bugs

    Enlève simplement le As var

  5. #5
    Membre régulier
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    277
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Août 2010
    Messages : 277
    Points : 122
    Points
    122
    Par défaut
    Merci cela fonctionne trés bien.

    J'ai aussi enlevé ca
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    hit.Type = DataGridViewHitTestType.RowHeader AndAlso
    sinon la condition n'était jamais remplie

    Par contre comment puis je savoir si la ligne cliqué était déja selectionné ou pas, afin de la déselectionner si c'était le cas?

    OU

    Puis je passer un parametre au délégué du genre currentrow.index en plus du tableau de ligne, car une fois dans le délégé on ne sais plus si la ligne était selectionnée ou pas.

    J'ai solutionné mon probleme en mettant un flag et en inversant la selection en fonction du flag sur click de cellule.
    Mais c'est pas super beau.

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 753
    Points
    39 753
    Par défaut
    Citation Envoyé par gilles_906 Voir le message
    J'ai aussi enlevé ca
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    hit.Type = DataGridViewHitTestType.RowHeader AndAlso
    sinon la condition n'était jamais remplie
    Si, si tu cliques sur l'en-tête de la ligne. Et comme ça tu as toujours le mode de sélection "normal" en cliquant ailleurs. Mais c'est peut-être pas ce que tu veux...

    Citation Envoyé par gilles_906 Voir le message
    Puis je passer un parametre au délégué du genre currentrow.index en plus du tableau de ligne, car une fois dans le délégé on ne sais plus si la ligne était selectionnée ou pas.
    Easy

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    dgv.BeginInvoke(New Action(Of DataGridViewRow(), Int32)(AddressOf ReselectRows), selectedRows, hit.RowIndex)
     
    ...
     
    Private Sub ReselectRows(rows As DataGridViewRow(), rowIndex As Int32)
     
         ...
     
    End Sub

  7. #7
    Membre régulier
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    277
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Août 2010
    Messages : 277
    Points : 122
    Points
    122
    Par défaut
    Merci beaucoup

  8. #8
    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 442
    Points
    4 442
    Par défaut
    bonjour gilles
    Pourquoi contraindre le user a travailler avec ses 2 mains?......
    Tu peux utiliser l'event dataGridView_RowHeaderMouseClick.

    1/Un click pour marquer "la row selectionne" avec feedback couleur .
    DGV l'ajoute de lui-meme a SelectedRows.
    Un ContextMenu dans l'event est associe à "la row selectionne" et on memorise dans son champ Tag l'index row...

    2/Un click droit sur un ToolStripMenuItem du ContextMenu(DeselectRowToolStripMenuItem) deselectionne la "row" courante ( DGV s'en charge de la retirer de SelectedRows) et on retablit le currentRowStyle memorise au lancement du form....
    le code:
    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
     
    Public Class Form1
    	'gere le style par defaut des rows non selectionnes
    	Private currentRowStyle As DataGridViewCellStyle = New DataGridViewCellStyle
    	Public Sub New()
     
    		' Cet appel est requis par le Concepteur Windows Form.
    		InitializeComponent()
     
    		' Ajoutez une initialisation quelconque après l'appel InitializeComponent().
    		'fill de la datable
    		Me.Personnel1TableAdapter1.Fill(Me.PersonnelDataSet1.Personnel1)
     
    		Me.DataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect
     
    		'liaison à datasource DS 
    		Me.DataGridView1.DataSource = Me.PersonnelDataSet1.Personnel1
     
    		'Memorise le  style par defaut des rows non selectionnes
    		currentRowStyle = Me.DataGridView1.RowsDefaultCellStyle
    	End Sub
    	'Get the selected row
    	'ContextMenuStrip Memorise index row dans prop Tag
    	'et change la couleur du row selectionne en Yellow 
    	Private Sub dgView_RowHeaderMouseClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles DataGridView1.RowHeaderMouseClick
     
    		Me.DataGridView1.Rows(e.RowIndex).Selected = True
    		Me.DataGridView1.Rows(e.RowIndex).DefaultCellStyle.BackColor = Color.Yellow
     
    		'
    		Me.DataGridView1.Rows(e.RowIndex).ContextMenuStrip = ContextMenuStrip1
    		Me.ContextMenuStrip1.Tag = e.RowIndex
    	End Sub
    	'un ToolStripMenuItem retire le row actuel de la selection
    	'avec FeedBack couleur en retablissant le currentRowStyle
    	Private Sub DeselectRowToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DeselectRowToolStripMenuItem.Click
    		Dim indexRow As Integer = CType(Me.ContextMenuStrip1.Tag, Integer)
    		Me.DataGridView1.Rows(indexRow).Selected = False
    		Me.DataGridView1.Rows(indexRow).DefaultCellStyle = currentRowStyle
    	End Sub
     
     
    End Class
    Evidemment au lancement il faut mettre le mode de selection du dgv à DataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect
    bon code...............

  9. #9
    Membre régulier
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    277
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Août 2010
    Messages : 277
    Points : 122
    Points
    122
    Par défaut
    Merci de ta réponse MABROUKI

    Justement je ne veux pas contraindre le user a utiliser ses deux mains c'est pourquoi je voulais intercepter le click droit et le remplacer par un ctrl+click droit, qui fait exactement ce que je veux.

    Le context menu ne me plait pas trop, je préfère qu'au deuxieme clique cela deselectionne la ligne.

    J'ai enlevé les header de lignes (plus sympa pour l'affichage et les DGV sont en lecture seule) et les lignes sont en fullrowselect

    L'idée de changer la couleur de la ligne est bonne, mais cela m'oblige ensuite a faire une boucle sur toutes les lignes pour savoir qui est sélectionné.

    En fait, je construis une requete en dynamique pour remplir un DGV en fonction de la selection faite sur 4 autre DGV. Il faut donc que la selection deselection soit le plus facile possible pour l'user, ce qui exclu le contextmenu click droit.

    Cela fonctionne trés bien avec le code de tomlev. De plus je peux selectionner aussi les lignes en restant appuyé sur le click gauche.

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

Discussions similaires

  1. Multi-selection dans une ComboBox ?
    Par Moloko dans le forum MFC
    Réponses: 5
    Dernier message: 07/07/2021, 17h26
  2. Cellule multi-ligne dans un datagridview
    Par bullet91 dans le forum Windows Forms
    Réponses: 0
    Dernier message: 22/06/2009, 13h25
  3. Réponses: 5
    Dernier message: 09/07/2007, 19h07
  4. Parcours d'un multi select dans une filelistbox
    Par tomy29 dans le forum Delphi
    Réponses: 7
    Dernier message: 29/12/2006, 10h04
  5. Multi selection dans un TbdGrid
    Par LolHol dans le forum Bases de données
    Réponses: 2
    Dernier message: 27/10/2005, 10h23

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