Using thumb to move transformed control produces weird behavior
Asked Answered
O

4

5

I've encountered a weird behavior when trying to use a thumb to move a control around on a canvas. When I add a control to a canvas and use Thumb DragDelta event to move it around everything looks good. But when I apply a rotate transform to the control dragging it around is bizarre. The control starts to circle around the cursor, and the bigger the angle the bigger the circle.

Does anyone know how to make thumb work with a transformed element? I've spent all day trying to figure it out and nothing smart is coming to my mind.

Thanks for your help!

Ocampo answered 14/2, 2012 at 22:13 Comment(4)
This depends on how you implemented the movingWellworn
I'm taking e.HorizontalChange and e.VerticalChange and then using them in Canvas.SetTop() and Canvas.SetLeft(). Is that what you are talking about?Ocampo
Also where (on which property) do you apply the rotate transform?Wellworn
I've tried both Layout and Render Transform, both seem to have the same issue.Ocampo
O
0

It appears that Thumb's HorizontalChange and VerticalChange don't play nicely when thumb is rotated. So, I'm just using cursor location in the canvas get my left and top offsets. Its not exactly accurate, but its close enough for what I'm trying to do.

Ocampo answered 20/2, 2012 at 15:57 Comment(0)
A
8

If you apply any rotating transform to FrameworkElement it means that the coordinates grid associated with it has rotated. Thus, any event handler of this FrameworkElement will be receive position values in own coordinates grid.

void DragThumb_DragDelta(object sender, DragDeltaEventArgs e)
{
    //You can use this values when RotateTransform is null
    double deltaHorizontal = e.HorizontalChange;
    double deltaVertical = e.VerticalChange;

    //Transform coordinates
    Vector v = Math2DHelper.RotateVector2d(e.HorizontalChange, e.VerticalChange, Math2DHelper.D2R(rotationInDegrees));

    //Right values
    deltaHorizontal = v.X;
    deltaVertical = v.Y;

    ...
}

Sample math2D helper

public static class Math2DHelper
{
    public static Vector RotateVector2d(double x0, double y0, double rad)
    {
        Vector result = new Vector();
        result.X = x0 * Math.Cos(rad) - y0 * Math.Sin(rad);
        result.Y = x0 * Math.Sin(rad) + y0 * Math.Cos(rad);
        return result;
    }

    public static double D2R(double degree)
    {
        return (degree%360)*Math.PI/180;
    }
}
Aggrieve answered 16/7, 2014 at 17:32 Comment(0)
H
5

I came across this problem and found the solution , maybe someone find it helpful ,you need to check for any transformation before drag thumb

private void Thumb_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
    {
        var thumb = dts as UIElement;
        var transform = thumb.RenderTransform as RotateTransform;
        Point dragDelta = new Point(e.HorizontalChange, e.VerticalChange);

            if (transform != null)
            {
                dragDelta = transform.Transform(dragDelta);
            }

            Canvas.SetLeft(thumb, Canvas.GetLeft(thumb) + dragDelta.X);
            Canvas.SetTop(thumb, Canvas.GetTop(thumb) + dragDelta.Y);

    }
Herb answered 13/5, 2016 at 6:31 Comment(0)
W
1

If you ditch the Canvas properties and apply the movement in the right order in a TransformGroup it should work:

<Thumb.RenderTransform>
    <TransformGroup>
        <TranslateTransform x:Name="translation" />
        <RotateTransform ... />
    </TransformGroup>
</Thumb.RenderTransform>
translation.X += e.HorizontalChange;
translation.Y += e.VerticalChange;

If you switch the order in the group you get the same behavior as when using Canvas.Left/Top.

(If you animated the rotation this will not help you)

Wellworn answered 14/2, 2012 at 22:44 Comment(6)
This works better, but Rotation is now done around the left top corner of the canvas and not around the rotated item itself. Any suggestion on how to get that fixed?Ocampo
So you are animating the rotation?Wellworn
No. I am calling InvalidateMeasure() on rotated item at the end of DragDelta event. Would that affect it?Ocampo
Possibly, when only using the above code it did not rotate for me.Wellworn
I think what is going on is this: my original item location is 0,0. I move item using translate transform to a 50,50 location. When rotation is applied, rotation is centered around 0,0 as its items actual non-translated location.Ocampo
I think I figured out a solution that will work for me. Instead of using e.HorizontalChange and e.VerticalChange I just use mouse position in the canvas at the end of the drag to figure out where my object should be moved. Its not exactly precise, but I think it will do for what I'm trying to achieve.Ocampo
O
0

It appears that Thumb's HorizontalChange and VerticalChange don't play nicely when thumb is rotated. So, I'm just using cursor location in the canvas get my left and top offsets. Its not exactly accurate, but its close enough for what I'm trying to do.

Ocampo answered 20/2, 2012 at 15:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.