这是一个WPF桌面应用。我正在使用Thumb
控件来旋转我的对象。虽然它总体上运行良好且平滑,但每次开始旋转时旋转角度都会突然跳跃。初始跳转后,旋转再次顺利进行。
很容易重现。这是完整的XAML:
<Window x:Class="TestWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Width="600" Height="600">
<Canvas>
<ContentControl x:Name="CC" Canvas.Left="300" Canvas.Top="300">
<Grid>
<Thumb DragDelta="Thumb_DragDelta">
<Thumb.Template>
<ControlTemplate>
<Ellipse Width="10" Height="10" Fill="Red" Margin="0,-150,0,0" />
</ControlTemplate>
</Thumb.Template>
</Thumb>
<Rectangle Width="100" Height="100" Stroke="Black" Fill="Yellow" />
</Grid>
<ContentControl.RenderTransform>
<RotateTransform x:Name="RT" />
</ContentControl.RenderTransform>
</ContentControl>
</Canvas>
</Window>
这是完整的代码隐藏:
Imports System.Windows.Controls.Primitives
Class TestWindow
Inherits Window
Private Sub Thumb_DragDelta(sender As Object, e As Primitives.DragDeltaEventArgs)
Dim T = DirectCast(sender, Thumb)
Dim RT = DirectCast(CC.RenderTransform, RotateTransform)
Dim Pos = Mouse.GetPosition(Me)
Dim PCenter As New Point(350, 350) 'Center of yellow square
Dim xDiff = Pos.X - PCenter.X
Dim yDiff = Pos.Y - PCenter.Y
Dim angle = Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI
RT.Angle = angle + 90
End Sub
End Class
单击红色拇指并旋转。它工作得很好。停止以任意角度旋转。再次单击红色拇指并开始旋转。旋转将首先进行大幅度的跳跃,然后再次开始平稳旋转。
问题在哪里,我该如何解决?
答案 0 :(得分:1)
您的RotateTransform
来源与代码隐藏中使用的中心点不匹配。
默认情况下,变换原点位于左上角,为(300; 300)
,而不是(350; 350)
。
当初始角度不为零时,这会导致角度计算无效。
使用
<ContentControl x:Name="CC" Canvas.Left="300" Canvas.Top="300" RenderTransformOrigin="0.5, 0.5">
<!--...-->
</ContentControl>
如果您无法更改RenderTransformOrigin
,则需要更正代码隐藏中的角度计算。
首先,使用正确的中心点:
Dim PCenter As New Point(300, 300)
然后请记住,您的拇指实际上并不对应您希望对象旋转的角度。拇指有一个偏移量。你需要考虑到这一点。
Dim offsetAngle = Math.Atan2(-25.0, 50.0) * 180 / Math.PI
Dim angle = Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI - offsetAngle
RT.Angle = angle
您可以将offsetAngle
设为const
(不知道如何在VB中执行此操作)。
那些-25.0
和50.0
来自哪里? 50.0
是拇指的水平偏移量,计算为Grid.ActualWidth / 2.0
(因为拇指水平居中)。 -25.0
是拇指的垂直偏移量,计算为(Grid.ActualHeight + Thumb.Margin.Top) / 2.0
(因为拇指位于Grid
之上)。