Introduction
Why is the DragDrop event never fired on the client?
Here is the code that you should already be familiar with from MSDN, I will quickly explain what isn't intuitive. On the target, "DragOver" event handler is important! Because you have to check the type of effect allowed and set it. If you don't, you never will get your DragDrop event!!!!!!
You will/may start with the assumption that, the effect will automatically be set. It isn't. Unless you have this line in your DragOver of the target!
if ((e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move) {
e.Effect = DragDropEffects.Move;
So, once you understand that, it's a piece of cake; you can basically cut and paste/edit the following code into your project and do whatever. And remember, you can only really put your breakpoints on the DragOver event of the target to get a reliable sense of what is going on!
using System;
using System.Drawing;
using System.Windows.Forms;
namespace Snip_DragNDrop
{
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.ListBox ListDragSource;
private System.Windows.Forms.ListBox ListDragTarget;
private System.Windows.Forms.CheckBox UseCustomCursorsCheck;
private System.Windows.Forms.Label DropLocationLabel;
private int indexOfItemUnderMouseToDrag;
private int indexOfItemUnderMouseToDrop;
private Rectangle dragBoxFromMouseDown;
private Point screenOffset;
private Cursor MyNoDropCursor;
private Cursor MyNormalCursor;
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
public Form1()
{
this.ListDragSource = new System.Windows.Forms.ListBox();
this.ListDragTarget = new System.Windows.Forms.ListBox();
this.UseCustomCursorsCheck = new System.Windows.Forms.CheckBox();
this.DropLocationLabel = new System.Windows.Forms.Label();
this.SuspendLayout();
this.ListDragSource.Items.AddRange(new
object[] {"one", "two", "three", "four",
"five", "six", "seven", "eight",
"nine", "ten"});
this.ListDragSource.Location = new System.Drawing.Point(10, 17);
this.ListDragSource.Size = new System.Drawing.Size(120, 225);
this.ListDragSource.MouseDown += new
System.Windows.Forms.MouseEventHandler(this.ListDragSource_MouseDown);
this.ListDragSource.QueryContinueDrag += new
System.Windows.Forms.QueryContinueDragEventHandler(
this.ListDragSource_QueryContinueDrag);
this.ListDragSource.MouseUp += new
System.Windows.Forms.MouseEventHandler(this.ListDragSource_MouseUp);
this.ListDragSource.MouseMove += new
System.Windows.Forms.MouseEventHandler(this.ListDragSource_MouseMove);
this.ListDragSource.GiveFeedback += new
System.Windows.Forms.GiveFeedbackEventHandler(this.ListDragSource_GiveFeedback);
this.ListDragTarget.AllowDrop = true;
this.ListDragTarget.Location = new System.Drawing.Point(154, 17);
this.ListDragTarget.Size = new System.Drawing.Size(120, 225);
this.ListDragTarget.DragOver +=
new System.Windows.Forms.DragEventHandler(this.ListDragTarget_DragOver);
this.ListDragTarget.DragDrop +=
new System.Windows.Forms.DragEventHandler(this.ListDragTarget_DragDrop);
this.ListDragTarget.DragEnter +=
new System.Windows.Forms.DragEventHandler(this.ListDragTarget_DragEnter);
this.ListDragTarget.DragLeave +=
new System.EventHandler(this.ListDragTarget_DragLeave);
this.UseCustomCursorsCheck.Location = new System.Drawing.Point(10, 243);
this.UseCustomCursorsCheck.Size = new System.Drawing.Size(137, 24);
this.UseCustomCursorsCheck.Text = "Use Custom Cursors";
this.DropLocationLabel.Location = new System.Drawing.Point(154, 245);
this.DropLocationLabel.Size = new System.Drawing.Size(137, 24);
this.DropLocationLabel.Text = "None";
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 270);
this.Controls.AddRange(new
System.Windows.Forms.Control[] {this.ListDragSource,
this.ListDragTarget, this.UseCustomCursorsCheck,
this.DropLocationLabel});
this.Text = "Drag and Drop Example";
this.ResumeLayout(false);
}
private void ListDragSource_MouseDown(object sender,
System.Windows.Forms.MouseEventArgs e)
{
indexOfItemUnderMouseToDrag = ListDragSource.IndexFromPoint(e.X, e.Y);
if (indexOfItemUnderMouseToDrag != ListBox.NoMatches) {
Size dragSize = SystemInformation.DragSize;
dragBoxFromMouseDown =
new Rectangle(new Point(e.X - (dragSize.Width /2),
e.Y - (dragSize.Height /2)), dragSize);
} else
dragBoxFromMouseDown = Rectangle.Empty;
}
private void ListDragSource_MouseUp(object sender,
System.Windows.Forms.MouseEventArgs e) {
dragBoxFromMouseDown = Rectangle.Empty;
}
private void ListDragSource_MouseMove(object sender,
System.Windows.Forms.MouseEventArgs e)
{
if ((e.Button & MouseButtons.Left) == MouseButtons.Left) {
if (dragBoxFromMouseDown != Rectangle.Empty &&
!dragBoxFromMouseDown.Contains(e.X, e.Y)) {
try {
MyNormalCursor = new Cursor("3dwarro.cur");
MyNoDropCursor = new Cursor("3dwno.cur");
} catch {
UseCustomCursorsCheck.Checked = false;
}finally {
screenOffset = SystemInformation.WorkingArea.Location;
DragDropEffects dropEffect =
ListDragSource.DoDragDrop(
ListDragSource.Items[indexOfItemUnderMouseToDrag],
DragDropEffects.All | DragDropEffects.Link);
if (dropEffect == DragDropEffects.Move) {
ListDragSource.Items.RemoveAt(indexOfItemUnderMouseToDrag);
if (indexOfItemUnderMouseToDrag > 0)
ListDragSource.SelectedIndex = indexOfItemUnderMouseToDrag -1;
else if (ListDragSource.Items.Count > 0)
ListDragSource.SelectedIndex =0;
}
if (MyNormalCursor != null)
MyNormalCursor.Dispose();
if (MyNoDropCursor != null)
MyNoDropCursor.Dispose();
}
}
}
}
private void ListDragSource_GiveFeedback(object sender,
System.Windows.Forms.GiveFeedbackEventArgs e)
{
if (UseCustomCursorsCheck.Checked) {
e.UseDefaultCursors = false;
if ((e.Effect & DragDropEffects.Move) == DragDropEffects.Move)
Cursor.Current = MyNormalCursor;
else
Cursor.Current = MyNoDropCursor;
}
}
private void ListDragTarget_DragOver(object sender,
System.Windows.Forms.DragEventArgs e)
{
if (!e.Data.GetDataPresent(typeof(System.String))) {
e.Effect = DragDropEffects.None;
DropLocationLabel.Text = "None - no string data.";
return;
}
if ((e.KeyState & (8+32)) == (8+32) &&
(e.AllowedEffect & DragDropEffects.Link) == DragDropEffects.Link) {
e.Effect = DragDropEffects.Link;
} else if ((e.KeyState & 32) == 32 &&
(e.AllowedEffect & DragDropEffects.Link) == DragDropEffects.Link) {
e.Effect = DragDropEffects.Link;
} else if ((e.KeyState & 4) == 4 &&
(e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move) {
e.Effect = DragDropEffects.Move;
} else if ((e.KeyState & 8) == 8 &&
(e.AllowedEffect & DragDropEffects.Copy) == DragDropEffects.Copy) {
e.Effect = DragDropEffects.Copy;
} else if ((e.AllowedEffect & DragDropEffects.Move) ==
DragDropEffects.Move) {
e.Effect = DragDropEffects.Move;
} else
e.Effect = DragDropEffects.None;
indexOfItemUnderMouseToDrop =
ListDragTarget.IndexFromPoint(ListDragTarget.PointToClient(new
Point(e.X, e.Y)));
if (indexOfItemUnderMouseToDrop != ListBox.NoMatches){
DropLocationLabel.Text = "Drops before item #" +
(indexOfItemUnderMouseToDrop + 1);
} else
DropLocationLabel.Text = "Drops at the end.";
}
private void ListDragTarget_DragDrop(object sender,
System.Windows.Forms.DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(System.String))) {
Object item = (object)e.Data.GetData(typeof(System.String));
if (e.Effect == DragDropEffects.Copy ||
e.Effect == DragDropEffects.Move) {
if (indexOfItemUnderMouseToDrop != ListBox.NoMatches)
ListDragTarget.Items.Insert(indexOfItemUnderMouseToDrop, item);
else
ListDragTarget.Items.Add(item);
}
}
DropLocationLabel.Text = "None";
}
private void ListDragSource_QueryContinueDrag(object sender,
System.Windows.Forms.QueryContinueDragEventArgs e) {
ListBox lb = sender as ListBox;
if (lb != null) {
Form f = lb.FindForm();
if (((Control.MousePosition.X - screenOffset.X) < f.DesktopBounds.Left) ||
((Control.MousePosition.X - screenOffset.X) > f.DesktopBounds.Right) ||
((Control.MousePosition.Y - screenOffset.Y) < f.DesktopBounds.Top) ||
((Control.MousePosition.Y - screenOffset.Y) > f.DesktopBounds.Bottom)) {
e.Action = DragAction.Cancel;
}
}
}
private void ListDragTarget_DragEnter(object sender,
System.Windows.Forms.DragEventArgs e) {
DropLocationLabel.Text = "None";
}
private void ListDragTarget_DragLeave(object sender, System.EventArgs e) {
DropLocationLabel.Text = "None";
}
}
}[C++]
using namespace System;
using namespace System::Drawing;
using namespace System::Windows::Forms;
namespace Snip_DragNDrop {
public __gc class Form1 : public System::Windows::Forms::Form {
private:
System::Windows::Forms::ListBox* ListDragSource;
System::Windows::Forms::ListBox* ListDragTarget;
System::Windows::Forms::CheckBox* UseCustomCursorsCheck;
System::Windows::Forms::Label* DropLocationLabel;
Int32 indexOfItemUnderMouseToDrag;
Int32 indexOfItemUnderMouseToDrop;
Rectangle dragBoxFromMouseDown;
Point screenOffset;
System::Windows::Forms::Cursor* MyNoDropCursor;
System::Windows::Forms::Cursor* MyNormalCursor;
public:
Form1() {
this->ListDragSource = new System::Windows::Forms::ListBox();
this->ListDragTarget = new System::Windows::Forms::ListBox();
this->UseCustomCursorsCheck = new System::Windows::Forms::CheckBox();
this->DropLocationLabel = new System::Windows::Forms::Label();
this->SuspendLayout();
Object* temp0 [] = {
S"five", S"six", S"seven", S"eight",
S"nine", S"ten"};
this->ListDragSource->Items->AddRange(temp0);
this->ListDragSource->Location = System::Drawing::Point(10, 17);
this->ListDragSource->Size = System::Drawing::Size(120, 225);
this->ListDragSource->MouseDown +=
new System::Windows::Forms::MouseEventHandler(this,
ListDragSource_MouseDown);
this->ListDragSource->QueryContinueDrag +=
new System::Windows::Forms::QueryContinueDragEventHandler(this,
ListDragSource_QueryContinueDrag);
this->ListDragSource->MouseUp +=
new System::Windows::Forms::MouseEventHandler(this,
ListDragSource_MouseUp);
this->ListDragSource->MouseMove +=
new System::Windows::Forms::MouseEventHandler(this,
ListDragSource_MouseMove);
this->ListDragSource->GiveFeedback +=
new System::Windows::Forms::GiveFeedbackEventHandler(this,
ListDragSource_GiveFeedback);
this->ListDragTarget->AllowDrop = true;
this->ListDragTarget->Location = System::Drawing::Point(154, 17);
this->ListDragTarget->Size = System::Drawing::Size(120, 225);
this->ListDragTarget->DragOver +=
new System::Windows::Forms::DragEventHandler(this,
ListDragTarget_DragOver);
this->ListDragTarget->DragDrop +=
new System::Windows::Forms::DragEventHandler(this,
ListDragTarget_DragDrop);
this->ListDragTarget->DragEnter +=
new System::Windows::Forms::DragEventHandler(this,
ListDragTarget_DragEnter);
this->ListDragTarget->DragLeave +=
new System::EventHandler(this, ListDragTarget_DragLeave);
this->UseCustomCursorsCheck->Location =
System::Drawing::Point(10, 243);
this->UseCustomCursorsCheck->Size = System::Drawing::Size(137, 24);
this->UseCustomCursorsCheck->Text = S"Use Custom Cursors";
this->DropLocationLabel->Location = System::Drawing::Point(154, 245);
this->DropLocationLabel->Size = System::Drawing::Size(137, 24);
this->DropLocationLabel->Text = S"None";
this->AutoScaleBaseSize = System::Drawing::Size(5, 13);
this->ClientSize = System::Drawing::Size(292, 270);
System::Windows::Forms::Control* formControls[] =
{this->ListDragSource,
this->ListDragTarget, this->UseCustomCursorsCheck,
this->DropLocationLabel};
this->Controls->AddRange(formControls);
this->Text = S"Drag and Drop Example";
this->ResumeLayout(false);
}
private:
void ListDragSource_MouseDown(Object* ,
System::Windows::Forms::MouseEventArgs* e) {
indexOfItemUnderMouseToDrag =
this->ListDragSource->IndexFromPoint(e->X, e->Y);
if (indexOfItemUnderMouseToDrag != ListBox::NoMatches) {
System::Drawing::Size dragSize = SystemInformation::DragSize;
dragBoxFromMouseDown = Rectangle(Point(e->X - (dragSize.Width /2),
e->Y - (dragSize.Height /2)), dragSize);
} else
dragBoxFromMouseDown = Rectangle::Empty;
}
void ListDragSource_MouseUp(Object* ,
System::Windows::Forms::MouseEventArgs* ) {
dragBoxFromMouseDown = Rectangle::Empty;
}
private:
void ListDragSource_MouseMove(Object* ,
System::Windows::Forms::MouseEventArgs* e) {
if ((e->Button & MouseButtons::Left) == MouseButtons::Left) {
if (dragBoxFromMouseDown != Rectangle::Empty &&
!dragBoxFromMouseDown.Contains(e->X, e->Y)) {
try {
MyNormalCursor = new
System::Windows::Forms::Cursor(S"3dwarro.cur");
MyNoDropCursor =
new System::Windows::Forms::Cursor(S"3dwno.cur");
} catch (Exception*) {
this->UseCustomCursorsCheck->Checked = false;
}__finally {
screenOffset = SystemInformation::WorkingArea.Location;
DragDropEffects dropEffect =
this->ListDragSource->DoDragDrop(
ListDragSource->Items->Item[indexOfItemUnderMouseToDrag],
static_cast<DRAGDROPEFFECTS>(DragDropEffects::All |
DragDropEffects::Link));
if (dropEffect == DragDropEffects::Move) {
ListDragSource->Items->RemoveAt(
indexOfItemUnderMouseToDrag);
if (indexOfItemUnderMouseToDrag > 0)
ListDragSource->SelectedIndex =
indexOfItemUnderMouseToDrag -1;
else if (ListDragSource->Items->Count > 0)
ListDragSource->SelectedIndex =0;
}
if (MyNormalCursor != 0)
MyNormalCursor->Dispose();
if (MyNoDropCursor != 0)
MyNoDropCursor->Dispose();
}
}
}
}
private:
void ListDragSource_GiveFeedback(Object* ,
System::Windows::Forms::GiveFeedbackEventArgs* e) {
if (UseCustomCursorsCheck->Checked) {
e->UseDefaultCursors = false;
if ((e->Effect & DragDropEffects::Move)
== DragDropEffects::Move)
Cursor::Current = MyNormalCursor;
else
Cursor::Current = MyNoDropCursor;
}
}
private:
void ListDragTarget_DragOver(Object* ,
System::Windows::Forms::DragEventArgs* e) {
if (!e->Data->GetDataPresent(__typeof(System::String))) {
e->Effect = DragDropEffects::None;
DropLocationLabel->Text = S"None - no String* data.";
return;
}
if ((e->KeyState & (8+32)) == (8+32) &&
(e->AllowedEffect & DragDropEffects::Link)
== DragDropEffects::Link) {
e->Effect = DragDropEffects::Link;
} else if ((e->KeyState & 32) == 32 &&
(e->AllowedEffect & DragDropEffects::Link)
== DragDropEffects::Link) {
e->Effect = DragDropEffects::Link;
} else if ((e->KeyState & 4) == 4 &&
(e->AllowedEffect & DragDropEffects::Move) ==
DragDropEffects::Move) {
e->Effect = DragDropEffects::Move;
} else if ((e->KeyState & 8) == 8 &&
(e->AllowedEffect & DragDropEffects::Copy) ==
DragDropEffects::Copy) {
e->Effect = DragDropEffects::Copy;
} else if ((e->AllowedEffect &
DragDropEffects::Move) ==
DragDropEffects::Move) {
e->Effect = DragDropEffects::Move;
} else
e->Effect = DragDropEffects::None;
indexOfItemUnderMouseToDrop =
ListDragTarget->IndexFromPoint(
ListDragTarget->PointToClient(Point(e->X, e->Y)));
if (indexOfItemUnderMouseToDrop != ListBox::NoMatches) {
DropLocationLabel->Text =
String::Concat(S"Drops before item # ",
__box( (indexOfItemUnderMouseToDrop + 1)));
} else
DropLocationLabel->Text = S"Drops at the end.";
}
private:
void ListDragTarget_DragDrop(Object* ,
System::Windows::Forms::DragEventArgs* e) {
if (e->Data->GetDataPresent(__typeof(System::String))) {
Object* item = dynamic_cast<OBJECT*>(
e->Data->GetData(__typeof(System::String)));
if (e->Effect == DragDropEffects::Copy ||
e->Effect == DragDropEffects::Move) {
if (indexOfItemUnderMouseToDrop != ListBox::NoMatches)
ListDragTarget->Items->Insert(
indexOfItemUnderMouseToDrop, item);
else
ListDragTarget->Items->Add(item);
}
}
DropLocationLabel->Text = S"None";
}
private:
void ListDragSource_QueryContinueDrag(Object* sender,
System::Windows::Forms::QueryContinueDragEventArgs* e) {
ListBox* lb = dynamic_cast<LISTBOX*>(sender);
if (lb != 0) {
Form* f = lb->FindForm();
if (((Control::MousePosition.X - screenOffset.X)
< f->DesktopBounds.Left) ||
((Control::MousePosition.X - screenOffset.X)
> f->DesktopBounds.Right) ||
((Control::MousePosition.Y - screenOffset.Y)
< f->DesktopBounds.Top) ||
((Control::MousePosition.Y - screenOffset.Y)
> f->DesktopBounds.Bottom)) {
e->Action = DragAction::Cancel;
}
}
}
private:
void ListDragTarget_DragEnter(Object* ,
System::Windows::Forms::DragEventArgs* ) {
DropLocationLabel->Text = S"None";
}
private:
void ListDragTarget_DragLeave(Object* ,
System::EventArgs* ) {
DropLocationLabel->Text = S"None";
}
};
}
[STAThread]
int main() {
Application::Run(new Snip_DragNDrop::Form1());
}
[Visual Basic, C#, C++]
The following example shows how to use the DragDropEffects enumeration to specify how data should be transferred between the controls involved in a drag-and-drop operation. This example assumes that your form includes a RichTextBox control and a Label control, and that the Label control is populated with a list of valid file names. When the user drags a file name onto the RichTextBox control, the control's DragEnter event is raised. Within the event handler, the DragEventArgs object's Effect property is initialized to DragDropEffects to indicate that the data referenced by the file path should be copied to the RichTextBox control.
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
RichTextBox1.AllowDrop = True
End Sub
Private Sub RichTextBox1_DragEnter(ByVal sender As Object, _
ByVal e As System.Windows.Forms.DragEventArgs) _
Handles RichTextBox1.DragEnter
If (e.Data.GetDataPresent("Text")) Then
e.Effect = DragDropEffects.Copy
End If
End Sub
Private Overloads Sub RichTextBox1_DragDrop(ByVal sender As _
Object, ByVal e As System.Windows.Forms.DragEventArgs) _
Handles RichTextBox1.DragDrop
RichTextBox1.LoadFile(e.Data.GetData("Text"), _
System.Windows.Forms.RichTextBoxStreamType.RichText)
End Sub
Private Sub ListBox1_MouseDown(ByVal sender As Object, ByVal e _
As System.Windows.Forms.MouseEventArgs) Handles ListBox1.MouseDown
Dim Lb As ListBox
Dim Pt As New Point(e.X, e.Y)
Dim Index As Integer
Lb = sender
Index = Lb.IndexFromPoint(Pt)
If Index >= 0 Then
Lb.DoDragDrop(Lb.Items(Index), DragDropEffects.Link)
End If
End Subprivate void Form1_Load(object sender, EventArgs e)
{
richTextBox1.AllowDrop = true;
}
private void listBox1_MouseDown(object sender,
System.Windows.Forms.MouseEventArgs e)
{
ListBox lb =( (ListBox)sender);
Point pt = new Point(e.X,e.Y);
int index = lb.IndexFromPoint(pt);
if(index>=0)
{
lb.DoDragDrop(lb.Items[index].ToString(), DragDropEffects.Link);
}
}
private void richTextBox1_DragEnter(object sender, DragEventArgs e)
{
if(e.Data.GetDataPresent("Text"))
e.Effect = DragDropEffects.Copy;
}
private void richTextBox1_DragDrop(object sender, DragEventArgs e)
{
richTextBox1.LoadFile((String)e.Data.GetData("Text"),
System.Windows.Forms.RichTextBoxStreamType.RichText);
}
So go ahead and give me zero for this article, but all I found was ultra bloated articles on drag and drop. I believe I have explained the only really confusing part of it.