问题
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!
回答1:
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;
}
}
回答2:
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);
}
回答3:
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)
回答4:
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.
来源:https://stackoverflow.com/questions/9284988/using-thumb-to-move-transformed-control-produces-weird-behavior