现象
在设计扫描控件时,发现一个问题,扫瞄线的旋转中心在设计器中播放动画时是完全绕着线的一个端点旋转的,但一旦运行起来,它的旋转中心就不是直线的端点了。
设计器中播放动画效果如下:
运行时的情况如下:
UI设计
以下为UI代码
<Page
x:Class="WpfApp.Page1"
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:local="clr-namespace:WpfApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="page"
Title="Page1"
d:DesignHeight="1000"
d:DesignWidth="1000"
RenderTransformOrigin="0,0"
ShowsNavigationUI="True"
mc:Ignorable="d">
<Page.Resources>
<Storyboard x:Key="Storyboard1">
<DoubleAnimationUsingKeyFrames
RepeatBehavior="3x"
Storyboard.TargetName="line"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)">
<EasingDoubleKeyFrame KeyTime="00:00:00" Value="0" />
<EasingDoubleKeyFrame KeyTime="00:00:06" Value="360" />
</DoubleAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="line" Storyboard.TargetProperty="(UIElement.RenderTransformOrigin)" RepeatBehavior="1x">
<EasingPointKeyFrame KeyTime="00:00:00" Value="0.2,0.2" />
<EasingPointKeyFrame KeyTime="00:00:06" Value="0.2,0.2" />
</PointAnimationUsingKeyFrames>
</Storyboard>
</Page.Resources>
<Grid x:Name="grid">
<Line
x:Name="line"
Fill="Red"
Stroke="Red"
StrokeThickness="3"
X1="200"
X2="300"
Y1="200"
Y2="300">
<Line.RenderTransform>
<TransformGroup>
<ScaleTransform />
<SkewTransform />
<RotateTransform />
</TransformGroup>
</Line.RenderTransform>
<Line.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard x:Name="beginStoryboard" Storyboard="{StaticResource Storyboard1}" />
</EventTrigger>
</Line.Triggers>
</Line>
</Grid>
</Page>
MSDN关于旋转中心设置
xaml中设置旋转中心的方法如下:
<object RenderTransformOrigin="xOrigin, yOrigin"/>
或:
<object>
<object.RenderTransformOrigin>
<Point X=" xOrigin " Y=" yOrigin "/>
</object.RenderTransformOrigin>
</object>
C#中则如下:
Button myButton = new Button();
myButton.Name = "myRenderTransformButton";
this.RegisterName(myButton.Name,myButton);
myButton.RenderTransformOrigin = new Point(0.5,0.5);
RenderTransformOrigin 结构值的使用 Point 有些非标准,即 Point 不表示坐标系中的绝对位置。 而是将介于 0 和 1 之间的值解释为每个 x,y 轴中当前元素范围的一个因子。 例如, (0.5,0.5) 将导致呈现转换在元素上居中,或者 (1,1) 会将呈现转换置于元素的右下角。 NaN 不是接受的值。
超过 0 和 1 的值也被接受,并将导致更非常规的转换效果。 例如,如果将 设置为 RenderTransformOrigin (5,5) ,然后应用 , RotateTransform则旋转点将远远超出元素本身的边界。 转换将在源自右下角的大圆圈中旋转元素。 原点可能位于其父元素内的某个位置,并且可能位于框架或视图外。 负点值类似,这些值将超出左上角的边界。
呈现转换不会影响布局,通常用于对元素进行动画处理或应用临时效果。
按上述MSDN的说法,将旋转中心的位置设置为了(0.2,0.2),但运行起来的情况就如前述所说。
也就是说设置是没有问题的,毕竟Line的起始点(200,200),Line的父控件继承了Page的宽高,就是宽1000、高1000,按旋转中心的设置方式就应该是(0.2,0.2)。
产生原因
由于设置的宽和高为设计时的宽高,设计时的宽高与运行时的宽高是不一样的。
解决办法
将设计时宽高 d:DesignHeight="1000" d:DesignWidth="1000" 改为Height="1000" Width="1000"即可解决问题。
设计时特性
WPF提供了9个设计时特性,也就是说涉及这9个设计时特性时,它的运行时就可能与设计时产生的效果不一样,这一定要注意。
d:DesignHeight d:DesignWidth d:DataContext
d:DesignInstance d:DesignData d:DesignSource
d:IsDesignTimeCreatable d:CreateList d:Type
参考链接
UIElement.RenderTransformOrigin 属性 (System.Windows) | Microsoft Learn