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.(MouseMove)オブジェクトを任意の位置にドラッグします。私のパネルで100ポイント。

3.(MouseLeftButtonUp) オブジェクトは、ドラッグしている場所に正しく配置されます。

今のところ問題はありません。しかし、2 回目のイベント チェーンを開始すると、次のようになります。

1.(MouseLeftButtonDown)ドラッグされたオブジェクトが後方に移動します:

                         CurrentPointerPosition + FIRSTPosition

2. (MouseMove)ドラッグ移動が実行されますが、MousePointer はドラッグされたオブジェクトから CurrentPointerPosition + FIRSTPosition にあります。

3.(MouseLeftButtonUp) は、初回と同様に正しく実行されました (ただし、明らかでした)。

MouseLeftButtonDown では、MouseDownPosition とドラッグされたオブジェクトの位置をリセットする必要があるようです...

なんで?私が間違っていることは何ですか?ありがとう!

4

2 に答える 2

2

MSDN の「TheKiller556」のおかげで、レイアウトの変更に従って、最終的に問題に対する正しいアプローチを見つけたので、REAL ユニバーサルで堅牢なドラッグ動作を作成しました。

RenderTransformsの問題を解決しないリンクは、複雑なロジックパネルでMarginプロパティALSO(テスト済み)で解決しているようです:

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));
        }
    }

これが、この奇妙な問題を抱えている/抱えるすべての人が、MSによるバグ/不明なデフォルトの可能性を見つけるためにWPFレイアウトプロセスを解決または深く掘り下げるのに役立つことを願っています。WPFレイアウトであるこの巨大な議論はまだ十分にわかっていないと思います。今のところ、IdentityとTranslation Matrixの間のMatrix製品にスカラー値があり、コンテナーレイアウトプロセスの基底変換に影響を与えていると思いますが、これは代数的な考慮事項にすぎず、MS実装での証明はありません。パネルの所有者に依存せずに、TranslateTransformを正しく使用する方法を皆さんに説明してください。みんなありがとう!私のコードの返信、考慮事項、説明を待っています。

于 2011-11-12T23:16:37.960 に答える