Comment faire pour empêcher l'auto-glisser-déposer dans un datagridview?
-
03-07-2019 - |
Question
J'implémente la fonctionnalité glisser-déposer entre deux vues de données. Cela fonctionne comme prévu, à une exception près: il est possible de glisser-déposer dans la même vue datagrid. Cela se traduit par des lignes en double. Je souhaite limiter les fonctionnalités afin que je ne puisse que faire glisser d'un datagridview à un autre. Est-ce que quelqu'un sait comment cela peut être réalisé? Je suppose qu’un test de frappe est nécessaire, mais je ne sais pas comment le mettre en œuvre ...
Le code que j'utilise est le suivant:
Private Sub dgvFMAvailable_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles dgvFMAvailable.MouseMove
If e.Button = Windows.Forms.MouseButtons.Left Then
Me.dgvFMAvailable.DoDragDrop(Me.dgvFMAvailable.SelectedRows, DragDropEffects.Move)
End If
End Sub
et
Private Sub dgvFMSelected_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles dgvFMSelected.DragDrop
Try
Me.SelectFM(CType(e.Data.GetData(GetType(DataGridViewSelectedRowCollection)), DataGridViewSelectedRowCollection))
Finally
e.Effect = DragDropEffects.None
End Try
End Sub
La solution
Juste une idée rapide. Et si vous maintenez le nom de la grille d’origine lorsque vous commencez le glisser-déposer? Lorsque vous effectuez la suppression, vérifiez le nom. S'ils sont le même objet, n'autorisez pas la suppression.
Autres conseils
Testez simplement l’égalité de référence lors de la suppression. Quelque chose comme ça:
If Object.ReferenceEquals(droppedThing, thingWhereItWasDropped)
' Don't drop it
Else
' Drop it
End If
Je n’ai pas trouvé de bonne réponse à cette question, bien qu’il semble que ce soit un problème courant. J'ai donc utilisé la réponse de gbianchi de la manière suivante:
public bool DraggingFromFileLinkDGV { get; set; }
void grdFiles_MouseDown(object sender, MouseEventArgs e)
{
this.DraggingFromFileLinkDGV = true;
}
void grdFiles_MouseLeave(object sender, EventArgs e)
{
this.DraggingFromFileLinkDGV = false;
}
void grdFiles_DragDrop(object sender, DragEventArgs e)
{
// Avoid DragDrop's on jittery DoubleClicks
if (this.DraggingFromFileLinkDGV) return;
// Your DragDrop code here ...
}
Maintenant, j’ai fait cela spécifiquement pour empêcher "errant". double-clic où la souris bouge un peu entre un double clic. Cela empêche les doubles clics de s'enregistrer en tant que drag drop et de répondre à la question des OP.
Remarquez, cela ne semble pas fonctionner à 100% du temps. Apparemment, certains événements sont " perdus " dans environ 1 cas sur 20. Je n'ai pas identifié exactement ce qui varie dans les situations où il enregistre une chute sur lui-même. Dans le cas d'empêcher l'enregistrement de doubles clics en tant que dragout, 95% est suffisant, car il vient tout juste d'être mis en place pour éviter les inconvénients. Si vous avez besoin de quelque chose d'efficacité à 100%, vous devrez peut-être essayer autre chose ou comprendre pourquoi cela ne fonctionne pas dans ces quelques cas.
Une solution consiste à stocker une description de chaîne de ce que vous faites glisser dans l'objet de données lorsque vous commencez à faire glisser, par exemple:
Dim dataObj As New DataObject
...
dataObj.SetText(G_SELF_DRAG_DROP_FLAG)
Ensuite, sur DragEnter, vérifiez si le drapeau est présent:
Public Sub ProcessAttachment_DragEnter(ByRef e As System.Windows.Forms.DragEventArgs)
' prevent dragging onto self
Dim s = e.Data.GetData(DataFormats.Text)
If s IsNot Nothing Then
If s.contains(G_SELF_DRAG_DROP_FLAG) Then
e.Effect = DragDropEffects.None
Exit Sub
End If
End If
...
End Sub
La définition de l'indicateur sur false dans l'événement MouseLeave
ne fonctionnait pas correctement pour moi. MouseLeave
a continué à être appelé dès que j'ai appelé DoDragDrop
.
Je l’ai enfin fait fonctionner comme suit:
A) I create a private bool DraggingFromHere flag
B) Right before calling DoDragDrop, I set this.DraggingFromHere = true
C) In the MouseUp event, I set this.DraggingFromHere = false
D) In the DragDro event, I simply to this:
if(this.DraggingFromHere) return;
Carlos Merighe