WPF绘图与动画(三)
图形的变形
WPF中的变形与UI元素是分开的。举个例子,你可以设计一个“向左旋转45度”的变形,然后把这个变形赋值给不同UI元素的变形控制属性,这些UI元素就都向左旋转45度了。这种将元素与变形控制属性分开的设计方案既减少了为UIElement类添加过的属性,又提高了变形类实例的复用性,可谓一举两得。这种设计思路非常符合策略模式中“有一个”比“是一个”更加灵活的思想。
控制变形的属性又两个,分别是:
RenderTransform:呈现变形,定义在UIElement类中。
LayoutTransform:布局变形,定义在FrameworkElement类中。
因为FrameworkElement派生自UIElement,而控件的基类Control类又派生自FrameworkElement,所以在控件级别两个属性你都能看到。这两个属性都是依赖属性,它们的数据类型都是Transform抽象类,也就是说,Transform类的派生类实均可用来为这两个属性赋值。
Transform抽象类的派生类有如下一些:
MatrixTransform:矩阵变形,把容纳被变形UI元素的矩形顶点看作一个矩阵进行变形。
RotateTransform:旋转变形,以给定的点为旋转中心,以角度为单位进行旋转变形。
ScaleTransform:坐标系变形,调整被变形元素的坐标系,可产生缩放效果。
SkewTransform:拉伸变形,可在横向和纵向上对呗变形元素进行拉伸。
TranslateTransform:偏移变形,使被变形元素在横向或纵向上偏移一个给定的值。
TransformGroup:变形组,可以把多个独立变形组合成为一个变形组、产生符合变形效果。
WPF的RenderTransform属性就是要起到这个作用,让UI元素呈现出来的属性与它本来的属性不一样!比如,一个按钮本来处在Canvas或者Grid的左上角,而我可以使用RenderTransform属性让其呈现在右下角并且向右旋转45°
<Window x:Class="WPFLearn.DrawAndAnimation.RenderTransform"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="RenderTransform" Height="500" Width="500">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Width="80" HorizontalAlignment="Left" VerticalAlignment="Top" Height="80" Content="Hello">
<Button.RenderTransform>
<!--复合变形-->
<TransformGroup>
<RotateTransform CenterX="40" CenterY="40" Angle="45"/>
<TranslateTransform X="300" Y="200"/>
</TransformGroup>
</Button.RenderTransform>
</Button>
</Grid>
</Window>
为什么需要呈现变形呢?答案是:为了效率!在窗体上移动UI元素本身会导致窗体布局的改变,而窗体布局的每一个(哪怕是细微的)变化都将导致所以窗体元素的尺寸测算函数、位置测算函数、呈现函数等的调用,造成系统资源占用激增、程序性能徒降。而使用呈现变形则不会遇到这样的问题,呈现变形只改变元素“出现在哪里”,所以不牵扯布局的改变、只涉及窗体的重绘。所以,当你需要制作动画的时候,请切记要使用RenderTransform。
布局变形
与呈现变形不同,布局变形会影响窗体的布局、导致窗体布局的重新测算。因为窗体布局的重新测算和绘制影响程序的性能,所以布局变形一般只用在静态变形上,而不用于制作动画。
<Window x:Class="WPFLearn.DrawAndAnimation.LayoutTransform"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="LayoutTransform" Height="300" Width="300">
<Grid>
<!--Layout-->
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!--Content-->
<Grid x:Name="titleBar1" Background="LightBlue" Grid.Column="0">
<TextBlock Text="Hello Transformer!" FontSize="24" HorizontalAlignment="Left" VerticalAlignment="Bottom">
<TextBlock.RenderTransform>
<RotateTransform Angle="-90"/>
</TextBlock.RenderTransform>
</TextBlock>
</Grid>
<Grid x:Name="titleBar2" Background="LightBlue" Grid.Column="1">
<TextBlock Text="Hello Transformer!" FontSize="24" HorizontalAlignment="Left" VerticalAlignment="Bottom">
<TextBlock.LayoutTransform>
<RotateTransform Angle="-90"/>
</TextBlock.LayoutTransform>
</TextBlock>
</Grid>
</Grid>
</Window>


浙公网安备 33010602011771号