RenderTransform Mouse.GetPosition

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

    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) When I click on the FIRST time on the Dragged Object,It is moving correctely.

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

3. (MouseLeftButtonUp) Объект правильно позиционируется ГДЕ Я ОСТАВИЛ ЕГО ПЕРЕТАСКИВАНИЕ.

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

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

                         CurrentPointerPosition + FIRSTPosition

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

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

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

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


person The Magnificient Macak    schedule 12.11.2011    source источник
comment
Новости: я обнаружил, что если я изменю код MouseLeftButtonUp, просто добавив this.AssociatedObject.RenderTransform = null; ›Перетаскиваемый объект действует как перетаскиваемый за счет упругого трения, каждый раз возвращаясь в исходное положение… Кажется, перетаскиваемый объект не обновляет свое положение после TranslateTransform… Все еще не решено ...   -  person The Magnificient Macak    schedule 12.11.2011
comment
stackoverflow.com/questions/2495039 / Кажется, у других людей такая же проблема, но никто не решил ее. ТОЛЬКО обходной путь, НЕ применимый ко ВСЕМ панелям ...   -  person The Magnificient Macak    schedule 12.11.2011
comment
social.msdn.microsoft .com / Forums / en-US / wpf / thread / Вот еще один, у которого такая же проблема ...   -  person The Magnificient Macak    schedule 13.11.2011
comment
И еще один: netframeworkdev.com/ Windows-презентации-Foundation-WPF /   -  person The Magnificient Macak    schedule 13.11.2011
comment
Этот вопрос немного запутан, можете ли вы точно и ясно сформулировать, в чем проблема?   -  person Kev    schedule 13.11.2011
comment
Мне очень жаль, если это кажется сложным, но я не могу найти более простого способа объяснить: код, который решает вопрос, находится в конце сообщения, но вопрос все еще открыт: как я могу перетащить UIElement вокруг общей панели с помощью TranslateTransform?   -  person The Magnificient Macak    schedule 13.11.2011


Ответы (2)


Благодаря «TheKiller556» на MSDN я наконец нашел правильный подход к проблеме, в соответствии с изменениями макета, так что создал НАСТОЯЩИЙ универсальный и надежный режим перетаскивания.

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

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

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

person The Magnificient Macak    schedule 13.11.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. На данный момент я только предполагаю, что в продукте Матрицы между Идентификацией и Матрицами перевода есть какое-то скалярное значение, которое может повлиять на изменение Базы в процессе компоновки контейнера, но это только алгебраическое рассмотрение, без каких-либо доказательств в реализации MS. Пожалуйста, объясните всем, КАК мы можем использовать TranslateTransform корректно и независимо от владельца панели. Большое спасибо всем! Жду ответов, соображений, ОБЪЯСНЕНИЙ моего кода.

person The Magnificient Macak    schedule 12.11.2011
comment
Этот код НЕ РАБОТАЕТ с другими типами панелей, как многие советы:… Использование RenderTransform предпочтительнее в Canvas.SetLeft и т. Д. Только в сценарии, когда вам нужно перетаскивать объекты на StackPanels, WrapPanels и т. Д. Таким образом, используя Transform может только простые вещи преобразить в аду ... - person The Magnificient Macak; 13.11.2011