RenderTransform Mouse.GetPosition - PullRequest
0 голосов
/ 12 ноября 2011

Хорошо, лучше с некоторыми исправлениями и применяется ТОЛЬКО к Х КООРДИНАТЕ: Учитывая следующий код:

    private Point MouseDownPosition;

     private void OnStartDrag(object sender, MouseButtonEventArgs e)
    {
        if (!this.AssociatedObject.IsMouseCaptured)
        {
            this.AssociatedObject.AddHandler(FrameworkElement.MouseMoveEvent, new MouseEventHandler(this.OnDrag));
            this.AssociatedObject.RenderTransform = new TranslateTransform();
            this.MouseDownPosition = Mouse.GetPosition(null);
            Mouse.Capture(this.AssociatedObject, CaptureMode.Element);
        }
    }
    private void OnDrag(object sender, MouseEventArgs e)
    {
        if (this.AssociatedObject.IsMouseCaptured)
        {
            this.AssociatedObject.AddHandler(FrameworkElement.MouseLeftButtonUpEvent, new MouseButtonEventHandler(this.OnStopDrag));
            TranslateTransform Translate = this.AssociatedObject.RenderTransform as TranslateTransform;
            Point CurrentPosition = Mouse.GetPosition(null); 
            Translate.X = CurrentPosition.X - this.MouseDownPosition.X;
        }
    }
    private void OnStopDrag(object sender, MouseButtonEventArgs e)
    {
        if (this.AssociatedObject.IsMouseCaptured)
        {
            this.AssociatedObject.ReleaseMouseCapture();
            this.AssociatedObject.RemoveHandler(FrameworkElement.MouseMoveEvent, new MouseEventHandler(this.OnDrag));
            this.AssociatedObject.RemoveHandler(FrameworkElement.MouseLeftButtonUpEvent, new MouseButtonEventHandler(this.OnStopDrag));
        }
    }

1. (MouseLeftButtonDown) Когда я нажимаю ПЕРВОЕ время на перетаскиваемом объекте, он движется правильно.

2. (MouseMove) Я перетаскиваю объект в произвольную позицию, напр. 100 очков прямо на моей панели.

3. (MouseLeftButtonUp) Объект расположен правильно, ГДЕ Я ОСТАВИЛ ЭТО ТЯНУТЬ.

До сих пор никаких проблем. Но когда я запускаю цепочку событий для ВТОРОГО ВРЕМЕНИ:

1. (MouseLeftButtonDown) Перетаскиваемый объект смещен Назад на:

                         CurrentPointerPosition + FIRSTPosition

2. (MouseMove) Перетаскивание выполняется, но MousePointer находится в CurrentPointerPosition + FIRSTPosition ОТ перетаскиваемого объекта.

3. (MouseLeftButtonUp) выполняется правильно, как в первый раз (но это было очевидно).

Похоже, что при MouseLeftButtonDown MouseDownPosition и положение перетаскиваемого объекта должны быть сброшены ...

Почему? Что я делаю не так? Спасибо!

Ответы [ 2 ]

2 голосов
/ 13 ноября 2011

Благодаря «TheKiller556» на MSDN я наконец-то нашел правильный подход к проблеме, в соответствии с изменениями компоновки, поэтому сделал РЕАЛЬНОЕ универсальное и надежное поведение перетаскивания.

Ссылка, которая не решает проблему RenderTransforms, кажется, решается с помощью свойства Margin ALSO (проверено) на сложных логических панелях:

http://social.msdn.microsoft.com/Forums/en/wpf/thread/eb3a912b-1046-4902-8c7a-bbc0566209c0

Я надеюсь, что в будущем, в любом случае, будет более глубокое объяснение проблем трансформации. Спасибо всем! (Я знаю, что не могу голосовать сам, но если кто-то внимательно изучит мой пост, я действительно нашел решение, поэтому, если это возможно, я хотел бы знать, могу ли я получить за это несколько баллов.) Еще раз спасибо!

0 голосов
/ 13 ноября 2011

Хорошо, после рытья часов я наконец нашел РЕШЕНИЕ. Я молюсь, чтобы все, кто действительно имел опыт работы с WPF / Silverlight, объяснили мне (и другим, у кого была эта проблема) ПОЧЕМУ точно работает мой код, потому что, искренне, я не могу найти логическую причину:

public class DragBehavior : Behavior<FrameworkElement>
{
    #region Constructors

    static DragBehavior()
    {
    }
    public DragBehavior()
    {
    }

    #endregion

    private Point MouseDownPosition;

    protected override void OnAttached()
    {
        this.AssociatedObject.AddHandler(FrameworkElement.MouseLeftButtonDownEvent, new      MouseButtonEventHandler(this.OnStartDrag));
        this.AssociatedObject.RenderTransform = new TranslateTransform();
        this.AssociatedObject.UpdateLayout();
        base.OnAttached();
    }
    protected override void OnDetaching()
    {
        this.AssociatedObject.RenderTransform = null;
        this.AssociatedObject.RemoveHandler(FrameworkElement.MouseLeftButtonDownEvent, new MouseButtonEventHandler(this.OnStartDrag));
        base.OnDetaching();
    }

    private void OnStartDrag(object sender, MouseButtonEventArgs e)
    {
        if (!this.AssociatedObject.IsMouseCaptured)
        {
            this.AssociatedObject.AddHandler(FrameworkElement.MouseMoveEvent, new MouseEventHandler(this.OnDrag));
            this.MouseDownPosition = Mouse.GetPosition(this.AssociatedObject);

            Mouse.Capture(this.AssociatedObject, CaptureMode.SubTree);
        }
    }
    private void OnDrag(object sender, MouseEventArgs e)
    {
        if (this.AssociatedObject.IsMouseCaptured)
        {
            this.AssociatedObject.AddHandler(FrameworkElement.MouseLeftButtonUpEvent, new MouseButtonEventHandler(this.OnStopDrag));
            TranslateTransform Translate = this.AssociatedObject.RenderTransform as TranslateTransform;
            Translate.X = (Mouse.GetPosition(this.AssociatedObject.Parent as FrameworkElement).X - this.MouseDownPosition.X) / 3;
            Translate.Y = (Mouse.GetPosition(this.AssociatedObject.Parent as FrameworkElement).Y - this.MouseDownPosition.Y) / 3;

            Point Position = new Point(Translate.X,Translate.Y);
            Size Size = this.AssociatedObject.DesiredSize;
            Rect Bounds = new Rect(Position,Size);

            this.AssociatedObject.Arrange(this.AssociatedObject.RenderTransform.TransformBounds(Bounds));
        }
    }
    private void OnStopDrag(object sender, MouseButtonEventArgs e)
    {
        if (this.AssociatedObject.IsMouseCaptured)
        {
            this.AssociatedObject.ReleaseMouseCapture();
            this.AssociatedObject.RemoveHandler(FrameworkElement.MouseMoveEvent, new MouseEventHandler(this.OnDrag));
            this.AssociatedObject.RemoveHandler(FrameworkElement.MouseLeftButtonUpEvent, new MouseButtonEventHandler(this.OnStopDrag));
        }
    }

Надеюсь, это поможет всем, кто столкнулся / будет иметь эту странную проблему, чтобы решить или углубиться в процесс компоновки WPF, чтобы найти любую возможную ошибку / неизвестные значения по умолчанию от MS. Я думаю, я еще недостаточно знаю этот огромный аргумент, который является WPF Layout. На данный момент, я только предполагаю, что в продукте Matrix есть некоторая скалярная величина между Identity и матрицами перевода, возможно, влияющая на изменение Basis в процессе компоновки контейнера, но это только алгебраическое соображение, без какого-либо доказательства в реализации MS. Пожалуйста, объясните всем, КАК мы можем использовать TranslateTransform корректно и независимо от владельца Panel. Спасибо всем большое! Жду ответов, соображений, ПОЯСНЕНИЙ моего кода.

...