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
Était-ce utile?

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top