使用Red-Gate工具,我們檢測到System.Windows.DataObject持有對dragObject(一個框架元素)的引用,該操作從完成後的一段漫長的操作中暫停。從拖放中刪除WPF內存
如何一次「清除」拖動對象DragDrop.DoDragDrop?有沒有辦法通過這個通過一個null並讓它通過?
使用Red-Gate工具,我們檢測到System.Windows.DataObject持有對dragObject(一個框架元素)的引用,該操作從完成後的一段漫長的操作中暫停。從拖放中刪除WPF內存
如何一次「清除」拖動對象DragDrop.DoDragDrop?有沒有辦法通過這個通過一個null並讓它通過?
我剛剛發現了這顆寶石,我的解決方案是使用WeakReference來拖動數據項。
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)
{
....
}
首先a big thanks to Ian Oakes for his 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;
}
一些言論:
你不需要成員變量,使'SomeDragDropData'本地,然後用'GC.KeepAlive(_dragDropData)'替換'_dragDropData = null;'。 ['GC.KeepAlive'](http://msdn.microsoft.com/en-us/library/system.gc.keepalive.aspx)方法旨在完成這個確切的工作(保持一個額外的長度所以它不會被丟棄,但不會對數據做任何事情) –
哇:這是一個真正的好方法。關於爲什麼這會起作用的簡短解釋:DoDragDrop()將只在拖放操作完成後才能完成執行。因此,執行DoDragDrop()的函數始終保存對數據對象的最後一個強引用,並且只會在拖放操作完成後才釋放它。 –