Reputation: 6152
I'm implementing drag and drop functionality between two datagridviews. This works as intended with one exception: it is possible to drag and drop within the same datagridview. This results in duplicated rows. I want to limit the functionality so that I can only drag from one datagridview to another. Does anyone know how this can be achieved? I'm guessing some kind of hit test is required but I'm not sure how to implement this...
The code I am using is as follows:
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
and
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
Upvotes: 3
Views: 3516
Reputation: 135
Setting the flag to false in the MouseLeave
event did not work correctly for me. MouseLeave
kept being called as soon as I called DoDragDrop
.
I finally got it to work right as follows:
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 A Merighe
Upvotes: 0
Reputation: 7334
One way is to store a string description of what you are dragging in the DataObject when you start dragging, ie:
Dim dataObj As New DataObject
...
dataObj.SetText(G_SELF_DRAG_DROP_FLAG)
Then on DragEnter check to see if the flag is there:
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
Upvotes: 0
Reputation: 1339
I couldn't find a good answer for this, although it seems like it must be a commonly encountered problem. So I used gbianchi's answer in the following way:
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 ...
}
Now, I actually did this specifically to prevent "wandering" double clicks where the mouse moves a bit between a double click. This prevents double clicks registering as drag drops as well as answering the OPs question.
Mind you, it doesn't appear to work 100% of the time. Apparently some events are "lost" in like 1 out 20 cases. I haven't identified exactly what varies in those situations where it registers a drop onto itself. In the case of preventing double clicks registering as drag drops, 95% is good enough because it was just being put in place to avoid the annoyance. If you need something that is 100% effective, you may have to try something else or figure out why it doesn't work in those few cases.
Upvotes: 0
Reputation: 234584
Simply test for reference equality when dropping. Something like this:
If Object.ReferenceEquals(droppedThing, thingWhereItWasDropped)
' Don't drop it
Else
' Drop it
End If
Upvotes: 0
Reputation: 2138
Just a quick idea. What if when you start the drag you hold the name of the origin grid. When you do the drop check the name, if they are the same object then don't allow the drop.
Upvotes: 1