I think your code in the original question and your solution is far too simple.
You should use separate events to select an object (MouseDown) and to initiate the drag drop operation (MouseMove).
In my code example DragDropEffects is set to 'Move' if the item was dropped onto listbox2. In that case it's ok to delete the item from listbox1.
In the other situation where the item has been dragged and the mouse button released when not over listbox2 the effect will be 'None'. Now we delete only if the cursor is outside the bounds of the form.
private Object itemToDrag;
private void listBox1_MouseDown(object sender, MouseEventArgs e) {
itemToDrag = null;
if (e.Button == MouseButtons.Left) {
Int32 idx = listBox1.IndexFromPoint(e.Location);
if (idx != ListBox.NoMatches) {
itemToDrag = listBox1.Items[idx];
Debug.Print("Item selected for drag: {0}", itemToDrag);
}
}
}
private void listBox1_MouseMove(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Left && itemToDrag != null) {
Debug.Print("DragDrop starting");
DragDropEffects effect = listBox1.DoDragDrop(itemToDrag, DragDropEffects.Move);
Debug.Print("DragDrop ended : Effect {0}", effect);
if (effect == DragDropEffects.Move) {
Debug.Print("Item moved");
listBox1.Items.Remove(itemToDrag);
} else if (effect == DragDropEffects.None) {
if (!this.DesktopBounds.Contains(Cursor.Position)) {
Debug.Print("Item deleted");
listBox1.Items.Remove(itemToDrag);
}
}
itemToDrag = null;
}
}
private void listBox2_DragDrop(object sender, DragEventArgs e) {
String droppedItem = (String)e.Data.GetData(DataFormats.StringFormat);
Debug.Print("listbox2 DragDrop {0}", droppedItem);
listBox2.Items.Add(droppedItem);
}
private void listBox2_DragEnter(object sender, DragEventArgs e) {
e.Effect = DragDropEffects.Move;
Debug.Print("DragEnter listbox2");
}
Alan.