2012-05-18 113 views
4

使用Red-Gate工具,我們檢測到System.Windows.DataObject持有對dragObject(一個框架元素)的引用,該操作從完成後的一段漫長的操作中暫停。從拖放中刪除WPF內存

如何一次「清除」拖動對象DragDrop.DoDragDrop?有沒有辦法通過這個通過一個null並讓它通過?

回答

5

我剛剛發現了這顆寶石,我的解決方案是使用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) 
{ 
    .... 
} 
+0

哇:這是一個真正的好方法。關於爲什麼這會起作用的簡短解釋:DoDragDrop()將只在拖放操作完成後才能完成執行。因此,執行DoDragDrop()的函數始終保存對數據對象的最後一個強引用,並且只會在拖放操作完成後才釋放它。 –

1

首先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; 
} 

一些言論:

  • 這部作品的原因是因爲的DoDragDrop塊,直到用戶觸發的拖放操作。因此,只有在拖放操作完成後,_dragDropData纔會爲空。
  • 將_dragDropData設爲成員變量非常重要。僅僅使它成爲局部變量是不夠的:當垃圾收集器被觸發時,對象可能會被處置掉。這導致很難重現錯誤,因爲它不是因爲垃圾收集器被觸發而必須清理對象。從我看到的只有當大量內存被分配和釋放時纔得到清理
+2

你不需要成員變量,使'SomeDragDropData'本地,然後用'GC.KeepAlive(_dragDropData)'替換'_dragDropData = null;'。 ['GC.KeepAlive'](http://msdn.microsoft.com/en-us/library/system.gc.keepalive.aspx)方法旨在完成這個確切的工作(保持一個額外的長度所以它不會被丟棄,但不會對數據做任何事情) –