使用Red-Gate工具,我们检测到System.Windows.DataObject正在持有对dragObject(一个框架元素)的引用,该元素已经在操作完成���长时间挂起。
如何在DragDrop.DoDragDrop后“清除”拖放对象?是否有一种方法可以传递null并使其直接穿过?
如何在DragDrop.DoDragDrop后“清除”拖放对象?是否有一种方法可以传递null并使其直接穿过?
DataObject data = new DataObject(new WeakReference(this.draggedData));
DragDrop.DoDragDrop((DependencyObject)sender, data, DragDropEffects.Move);
然后在下拉菜单中选择
var draggedItem = e.Data.GetData(this.format.Name) as WeakReference;
if (draggedItem != null && draggedItem.IsAlive)
{
....
}
首先非常感谢Ian Oakes提供的解决方案。然而,我需要稍微改变一下:我必须确保即使垃圾收集器在此期间运行,丢弃操作也始终有效。以下是解决方案:
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;
}
一些备注:
SomeDragDropData
设为局部变量,然后用 GC.KeepAlive(_dragDropData)
替换 _dragDropData = null;
。GC.KeepAlive
方法旨在完成这个任务(保持引用一段额外的时间,以便它不会被处理但又不对数据进行任何操作)。 - Scott Chamberlain