First of all, many thanks to Jan Oaks for his decision . However, I needed a small option: I had to make sure that the drop always worked, even if the garbage collector ran in the meantime. Here is the solution:
public partial class DragDropDemo : Window { private SomeDragDropData _dragDropData; private void OnMouseMove(object sender, MouseEventArgs e) { if (e.LeftButton == MouseButtonState.Pressed) { _dragDropData = new SomeDragDropData { Text = "Some drag data" }; var dataObject = new DataObject("SomeObjectTypeId", new WeakReference<SomeDragDropData>(_dragDropData)); DragDrop.DoDragDrop((DependencyObject)sender, dataObject, DragDropEffects.Move); _dragDropData = null; } } private void OnDrop(object sender, DragEventArgs e) { var weakReferenceData = e.Data.GetData("SomeObjectTypeId") as WeakReference<SomeDragDropData>; if (weakReferenceData != null && weakReferenceData.IsAlive) MessageBox.Show(weakReferenceData.Target.Text); } } public class SomeDragDropData { public string Text; }
Some notes:
- The reason for this is that DoDragDrop blocks until the user performs a reset operation. Therefore, _dragDropData becomes null only after the drag and drop operation is completed.
- It is very important to make _dragDropData a member variable. Just making it a local variable is not enough: when the garbage collector starts, the object can be deleted. This makes it very difficult to reproduce the error, because it is not because the garbage collector is started, that the object is necessarily cleared. From what I saw, it only clears when a large memory is allocated and freed.
source share