Bonjour
un datatable public n'est pas une bonne pratique ça expose tes données à n'importe qui (y compris un programme extérieur).
Tu trouveras ici plusieurs façons de faire plus conseillées
https://codes-sources.commentcamarche.net/faq/11107-interactions-entre-form-en-net-c-et-vb-net
Pour ton problème à proprement parlé, j'ai peut-être une solution à base de collection de classe métier, mais ça t'obligerait à revoir ton architecture pour ne plus te servir de datatable (sauf éventuellement à la lecture initiale de ta base de données et à l'écriture des updates).
Quand j'étais petit, la mer Morte n'était que malade.
George Burns
Bonsoir,
Mon projet test est terminé. Il est possible de copier des sélections de lignes d'un DataGridView vers lui-même, ou vers son "avatar" d'une autre instance, ou aussi vers un autre DataGridView de la même instance ou d'une autre.
Soit un Form nommé FDragDrop contenant 2 DataGridView DGV1 et DGV2. Le DGV1 est chargé par des données de test lors de son Load. Le DoubleClick du Form ouvre une nouvelle instance, laquelle peut aussi être double-cliquée, et ainsi de suite ...
Voici le code de ce Form :
Public Class FDragDrop Private Sub Form1_DoubleClick(sender As Object, e As EventArgs) Handles Me.DoubleClick Dim F2 As New FDragDrop F2.Show() End Sub Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load ' Pour les tests DGV1.Columns.Add("Col1", "Col.1") DGV1.Columns.Add("Col2", "Col.2") DGV1.Rows.Add("1", "az") DGV1.Rows.Add("2", "aze") DGV1.Rows.Add("3", "azer") DGV1.Rows.Add("4", "azert") DGV1.Rows.Add("5", "azerty") DGV2.Columns.Add("Col1", "Col.1") DGV2.Columns.Add("Col2", "Col.2") ' Réglages nécessaires DGV1.AllowDrop = True DGV1.SelectionMode = DataGridViewSelectionMode.FullRowSelect DGV2.AllowDrop = True DGV2.SelectionMode = DataGridViewSelectionMode.FullRowSelect End Sub Dim SelectionFinie As Boolean ' Sélectionner et démarrer le DragDrop à partir de DGV1 Private Sub DGV1_MouseDown(sender As Object, e As MouseEventArgs) Handles DGV1.MouseDown If (e.Button = MouseButtons.Left) Then If SelectionFinie Then DGV1.DoDragDrop(DGV1.SelectedRows, DragDropEffects.Copy) SelectionFinie = False Else DGV1.ClearSelection() End If Else SelectionFinie = False End If End Sub ' Sélectionner et démarrer le DragDrop à partir de DGV2 Private Sub DGV2_MouseDown(sender As Object, e As MouseEventArgs) Handles DGV2.MouseDown If (e.Button = MouseButtons.Left) Then If SelectionFinie Then ' DGV2.DoDragDrop(DGV2.SelectedRows, DragDropEffects.Copy) SelectionFinie = False Else DGV2.ClearSelection() End If Else SelectionFinie = False End If End Sub ' Fin de sélection sur DGV1 Private Sub DGV1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles DGV1.MouseUp If (DGV1.SelectedRows.Count > 0) Then SelectionFinie = True End If End Sub ' Fin de sélection sur DGV2 Private Sub DGV2_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles DGV2.MouseUp If (DGV2.SelectedRows.Count > 0) Then SelectionFinie = True End If End Sub ' Vérifier la présence de données à l'entrée du processus de Drag-Drop lancé de DGV1 Private Sub DGV1_DragEnter(sender As Object, e As DragEventArgs) Handles DGV1.DragEnter If (e.Data Is Nothing) Then e.Effect = DragDropEffects.None Else e.Effect = DragDropEffects.Copy End If End Sub ' Vérifier la présence de données à l'entrée du processus de Drag-Drop lancé de DGV2 Private Sub DGV2_DragEnter(sender As Object, e As DragEventArgs) Handles DGV2.DragEnter If (e.Data Is Nothing) Then e.Effect = DragDropEffects.None Else e.Effect = DragDropEffects.Copy End If End Sub ' Déposer dans DGV1 les données capturées par le processus Drag-Drop Private Sub DGV1_DragDrop(sender As Object, e As DragEventArgs) Handles DGV1.DragDrop If (e.Data IsNot Nothing) Then Dim Selection As DataGridViewSelectedRowCollection = CType(e.Data.GetData(GetType(DataGridViewSelectedRowCollection)), DataGridViewSelectedRowCollection) Dim NCol As Integer = Selection(0).Cells.Count For Each R As DataGridViewRow In Selection Dim NR As DataGridViewRow = CType(R.Clone(), DataGridViewRow) For C As Integer = 0 To NCol - 1 NR.Cells(C).Value = R.Cells(C).Value Next DGV1.Rows.Add(NR) Next End If DGV1.ClearSelection() End Sub ' Déposer dans DGV2 les données capturées par le processus Drag-Drop Private Sub DGV2_DragDrop(sender As Object, e As DragEventArgs) Handles DGV2.DragDrop If (e.Data IsNot Nothing) Then Dim Selection As DataGridViewSelectedRowCollection = CType(e.Data.GetData(GetType(DataGridViewSelectedRowCollection)), DataGridViewSelectedRowCollection) Dim NCol As Integer = Selection(0).Cells.Count For Each R As DataGridViewRow In Selection Dim NR As DataGridViewRow = CType(R.Clone(), DataGridViewRow) For C As Integer = 0 To NCol - 1 NR.Cells(C).Value = R.Cells(C).Value Next DGV2.Rows.Add(NR) Next End If DGV2.ClearSelection() End Sub End Class
A toutes fins utiles, je dépose ce projet de test sur Dropbox pour quelques temps (j'espère ne pas contrevenir aux règles du forum) : https://www.dropbox.com/s/q5uyvdbri3xmfis/DragDrop.zip?dl=0
Cordialement,
Sam
Bonjour,
Mon problème de Drag-Drop entre DataGridView, même d'instances différentes, est résolu sans l'usage d'un DataTable Public, mais bien avec le e.Data inclus "d'office" dans l'évènement DrogDrop.
Voici les principaux extraits de codes :
Dim SelectionFinie As Boolean = False Private Sub DGV1_MouseDown(sender As Object, e As MouseEventArgs) Handles DGV1.MouseDown If (e.Button = MouseButtons.Left) Then If SeectionFinie Then DGV1.DoDragDrop(DGV1.SelectedRows, DragDropEffects.Copy) SelectionFinie = False End If End If End Sub Private Sub DGV1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles DGV1.MouseUp If (DGV1.SelectedRows.Count > 0) Then SelectionFinie = True End If End Sub Private Sub DGV2_DragEnter(sender As Object, e As DragEventArgs) Handles DGV2.DragEnter If (e.Data IsNot Nothing) Then e.Effect = DragDropEffects.Copy Else e.Effect = DragDropEffects.None End If End Sub Private Sub DGV2_DragDrop(sender As Object, e As DragEventArgs) Handles DGV2.DragDrop If SelectionFinie Then If (e.Data IsNot Nothing) Then Dim Selection As DataGridViewSelectedRowCollection = CType(e.Data.GetData(GetType(DataGridViewSelectedRowCollection)), DataGridViewSelectedRowCollection) Dim NCol As Integer = selected(0).Cells.Count For Each R As DataGridViewRow In Selection Dim NR As DataGridViewRow = CType(R.Clone(), DataGridViewRow) For C As Integer = 0 To NCol - 1 NR.Cells(C).Value = R.Cells(C).Value Next DGV2.Rows.Add(NR) Next End If End If End Sub
Cela fonctionne presque parfaitement compte tenu de a question initiale mais reste à améliorer.
Non seulement il est possible de copier de DGV1 vers DGV2 de la même instance et de DGV1 vers DGV2 d'une autre instance, je voudrais compléter de sorte à pouvoir copier de DGV2 vers DGV1, mais aussi de DGV1 vers DGV1 et de DGV2 vers DGV2, dans la même instance ou d'une instance à l'autre.
En fait, je veux imiter Excel : quand il y a plusieurs feuilles XLS visibles, il est possible de Drag-Drop de l'une à l'autre et il est toujours possible de Drag-Drop dans une même feuille.
Si quelqu'un a une idée ...
Bon week-end,
Sam
Bonsoir
je n'avais pas encore eu le temps de me pencher sur ta question.
Tant mieux si tu l'as partiellement résolue.
Pour tes prochains messages, merci de sélectionner Basic dans l'interface d'extraits de code.
Quand j'étais petit, la mer Morte n'était que malade.
George Burns
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre questionBonsoir,
J'ai modifié le libellé de mon raccourci vers ce site en y intégrant BASIC, j'espère que cela me permettra de m'en souvenir à l'avenir.
Peut-être aurais-tu une astuce qui me permettrait d'avancer encore.
Ce qui me bloque actuellement est que la sélection dans le DataGridView "source" reste active après l'évènement DragDrop du DataGridView "Cible". Ce détail m'empêche de faire correctement une nouvelle sélection dans le même DataGridView "source" car à mon etoru sur ce DGV, il y exécute le DragDrop et y colle (ajoute) les lignes de la sélection. Le ClearSelection n'a aucun effet sur cette sélection, c'est comme si elle était verrouillée par le processus du Drag-Drop.
Si tu as une idée ...
En tout cas, encore merci pour ton commentaire d'avant-hier, il m'a permis de chercher autre chose que mon DataTable publique.
Cordialement,
Sam
14 sept. 2022 à 16:34
Merci Whismeril pour le déplacement de la discussion. Quand j'ai dû désigner le forum, j'ai vu C#/.Net d'une part et VB d'autre part. Ne souhaitant pas le C# ni le VB 6.0, j'ai quand même opté pour C#/.Net.
Pour ce qui est du DataTable public, je connais le bien fondé de ta remarque. Mais jusque-là, c'est expérimental. A terme, cela doit devenir une classe. Mais il faudra bien qu'elle soit partagée car son but est de mettre les mêmes données à la disposition de plusieurs instances actives au même moment. Ces données peuvent être modifiées dans plusieurs instances d'un même Form.
Pas de problème pour le code puisque chaque instance accède au même DataTable. Pour le Copier-Coller, il y a le Clipboard mais l'usage du DataTable déjà présent est très simple.
Pour le Drag & Drop, cela ne fonctionne plus car je ne sais pas comment le charger et le relire pendant l'opération. Il ne m'est pas interdit de changer de technique, rien ne m'oblige d'utiliser le DataTable dans ce cas. Alors, si tu as une idée, je suis preneur ...
Merci d'avance ...
Sam