And*_*ndy 5 c# silverlight events memory-leaks behavior
我已经创建了一个自定义行为(没有混合)来拖动UIElements并获得你在光标下拖动的半透明缩略图(混合版本移动目标对象,这不是我需要的)
Anyhoo,代码实际上非常简单并且工作得很好,我遇到的问题是onDetaching()没有被调用,这意味着我对UIElement的事件没有解开.
这让我有点担心,因为我猜测行为没有脱离的唯一原因是因为它仍被某些东西引用.它不应该是UIElement它自己,因为我们在一个阶段有泄漏问题,但我们现在已经解决了它们,这通过WinDbg澄清.
关于它的唯一有趣(?)的事情是行为附加到项目控件中的图像,但这不应该有所作为吗?
这是我目前的代码:
public class DragBehavior : Behavior<UIElement>
{
private const double DRAG_DISTANCE = 20;
private const int DRAG_ICON_HEIGHT = 100;
Point m_firstPoint;
private bool m_isDragging = false;
private Popup m_dragPopup = null;
private Image m_draggedImage;
protected override void OnAttached()
{
this.AssociatedObject.MouseLeftButtonDown += new MouseButtonEventHandler(AssociatedObject_MouseLeftButtonDown);
this.AssociatedObject.MouseMove += new MouseEventHandler(AssociatedObject_MouseMove);
this.AssociatedObject.MouseLeftButtonUp += new MouseButtonEventHandler(AssociatedObject_MouseLeftButtonUp);
base.OnAttached();
}
void AssociatedObject_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
m_firstPoint = e.GetPosition(null);
m_isDragging = true;
}
void AssociatedObject_MouseMove(object sender, MouseEventArgs e)
{
if (m_isDragging)
{
Point currentPosition = e.GetPosition(null);
if (m_dragPopup == null)
{
double deltaX = currentPosition.X - m_firstPoint.X;
double deltaY = currentPosition.Y - m_firstPoint.Y;
double movement = Math.Sqrt((deltaX * deltaX) + (deltaY * deltaY));
if (movement > DRAG_DISTANCE)
{
// Get a screen shot of the element this behaviour is attached to
WriteableBitmap elementScreenshot = new WriteableBitmap(AssociatedObject, null);
// Create an image out of it
m_draggedImage = new Image();
m_draggedImage.Height = DRAG_ICON_HEIGHT;
m_draggedImage.Stretch = Stretch.Uniform;
m_draggedImage.Source = elementScreenshot;
m_draggedImage.Opacity = 0.4;
// Add the image to the popup
m_dragPopup = new Popup();
m_dragPopup.Child = m_draggedImage;
m_dragPopup.IsOpen = true;
m_dragPopup.UpdateLayout();
m_dragPopup.HorizontalOffset = currentPosition.X - m_draggedImage.ActualWidth/2;
m_dragPopup.VerticalOffset = currentPosition.Y - m_draggedImage.ActualHeight/2;
AssociatedObject.CaptureMouse();
}
}
else
{
m_dragPopup.HorizontalOffset = currentPosition.X - m_draggedImage.ActualWidth/2;
m_dragPopup.VerticalOffset = currentPosition.Y - m_draggedImage.ActualHeight/2;
}
}
}
void AssociatedObject_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (m_isDragging == true && m_dragPopup != null)
{
m_isDragging = false;
m_dragPopup.IsOpen = false;
m_dragPopup = null;
}
AssociatedObject.ReleaseMouseCapture();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
protected override void OnDetaching()
{
this.AssociatedObject.MouseLeftButtonDown -= new MouseButtonEventHandler(AssociatedObject_MouseLeftButtonDown);
this.AssociatedObject.MouseMove -= new MouseEventHandler(AssociatedObject_MouseMove);
this.AssociatedObject.MouseLeftButtonUp -= new MouseButtonEventHandler(AssociatedObject_MouseLeftButtonUp);
base.OnDetaching();
}
}
Run Code Online (Sandbox Code Playgroud)
我知道有两篇帖子我见过这个...
这个 - forums.silverlight.net/forums/p/142038/317146.aspx没有帮助,因为我试图强制GC无济于事,而这一个 - 自动调用OnDetaching()为Silverlight行为我不真正得到他们的探索,因为他们声称它将UIElement挂钩到引起它的行为,但是当根引用UIElement被打破时,对行为的根引用也将被删除,因此两者都变得可以被GC接受.
我希望这很简单,但如果没有,我会开始使用WinDbg看看实际发生了什么!
任何帮助深表感谢!:)
谢谢,
安迪.
您没有显示从何处调用分离。需要实际调用 object.Detach() (DragBehavior) 才能调用 OnDetaching() 方法。
如果您想在 AssociatedObject_MouseLeftButtonUp 事件处理程序中分离它,您可以在方法末尾调用 detach,只要您确实不需要对其执行任何其他操作。
void AssociatedObject_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (m_isDragging == true && m_dragPopup != null)
{
m_isDragging = false;
m_dragPopup.IsOpen = false;
m_dragPopup = null;
}
AssociatedObject.ReleaseMouseCapture();
this.Detach()
}
Run Code Online (Sandbox Code Playgroud)
我绝对不会对 GC 进行任何调用,这会对性能产生巨大影响。
| 归档时间: |
|
| 查看次数: |
1393 次 |
| 最近记录: |