0

好的,进行一些更正会更好,并且仅适用于 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)当我第一次点击拖动对象时,它正在正确移动。

2.(鼠标移动)我将对象拖动到任意位置。我的面板上有 100 分。

3.(MouseLeftButtonUp)对象被正确定位在我拖拽的地方。

到目前为止没有问题。但是当我第二次启动事件链时:

1.(MouseLeftButtonDown)被拖动的对象移到后面:

                         CurrentPointerPosition + FIRSTPosition

2. (MouseMove)执行拖动移动,但鼠标指针位于 CurrentPointerPosition + FIRSTPosition FROM 拖动对象。

3.(MouseLeftButtonUp) 与第一次一样正确执行(但很明显)。

似乎在 MouseLeftButtonDown 上,必须重置 MouseDownPosition 和拖动对象的位置......

为什么?我做错了什么?谢谢你!

4

2 回答 2

2

感谢 MSDN 上的“TheKiller556”,根据布局更改,我终于找到了解决问题的正确方法,从而实现了真正的通用且强大的拖动行为。

没有解决 RenderTransforms 问题的链接似乎在复杂逻辑面板上使用 Margin 属性 ALSO(tested) 解决:

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

我希望,在未来,无论如何转换问题都会有更深入的解释。谢谢大家!(我知道我自己不能投票,但是如果有人深入我的帖子,我有效地找到了解决方案,所以,如果可能的话,我想知道我是否可以为此加分。)再次感谢您!

于 2011-11-13T15:36:28.470 回答
0

好的,经过几个小时的挖掘,我终于找到了解决方案。我祈祷每个真正有 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 布局。目前,我只是假设Identity和Translation Matrixes之间的Matrix乘积中存在一些标量值,可能会影响容器布局过程中Basis的变化,但这只是代数考虑,在MS实现中没有任何证明。请向所有人解释我们如何正确使用 TranslateTransform 而不依赖于面板所有者。非常感谢大家!等待回复、考虑、解释我的代码。

于 2011-11-12T23:16:37.960 回答