Поведение Silverlight onDetaching не вызывается - PullRequest
5 голосов
/ 10 февраля 2011

Я создал пользовательское поведение (без наложения) для перетаскивания элементов UIE и получения полупрозрачного эскиза того, что вы перетаскиваете под курсором (версия с наложением перемещает целевой объект, а это не то, что мне нужно)

Во всяком случае, код на самом деле очень прост и работает хорошо, у меня проблема в том, что 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();
    }
}

Мне известны два сообщения, которые я видел по этому поводу ...

Этот файл - forums.silverlight.net/forums/p/142038/317146.aspx не помогает, поскольку я пытался заставить GC безрезультатно, а этот - Автоматический вызов OnDetaching () для Поведения Silverlight На самом деле я не понимаю их объяснения, поскольку они утверждают, что это связано с подключением UIElement к вызывающему его поведению, но, безусловно, когда корневая ссылка UIElement нарушена, корневая ссылка на поведение также будет удалена. и, следовательно, оба становятся подходящими для GC.

Я надеялся, что это будет просто, но если нет, я начну с WinDbg, чтобы посмотреть, что на самом деле происходит!

Любая помощь очень ценится! :)

Спасибо

Энди.

1 Ответ

0 голосов
/ 14 сентября 2011

Вы не показываете, откуда вызывается Отделение.Что-то должно действительно вызвать 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()
} 

Я определенно не буду делать какие-либо вызовы GC, которые могут иметь огромное влияние на производительность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...