天地不容忘祖求荣鹅粉 发表于 5 天前

不可不知的WPF转换(Transform)

在WPF开发中,经常会需要用到UI控件的2D转换(如:旋转,缩放,移动,倾斜等功能),本文以一些简单的小例子,简述如何通过Transform类实现FrameworkElement对象的2D转换,仅供学习分享使用,如有不足之处,还请指正。
 
什么是Transform?

 
转换(Transform)定义如何将控件从一个坐标空间映射或转换到另一个坐标空间。2D转换可以通过Matrix来实现,Matrix是一个3行3列的double值的集合。不过WPF还提供了多个Transform类,以便在不知道基础矩阵结构配置的情况下转换对象。
 
WPF提供了2D转换(Transform)类,常见的有以下几种:

[*]RotateTransform,按指定的角度(Angle)旋转元素。
[*]ScaleTansform,按指定的坐标方向(ScaleX和ScaleY)缩放元素。
[*]SkewTransform,按指定的角度(AngleX和AngleY)倾斜元素。
[*]TranslateTransform,按指定的X轴和Y轴移动元素,不过这种移动并非是真实的移动,只是呈现上的移动。
为了创建更复杂的转换(Transform),WPF还提供了组合转换。如下所示:

[*]TransformGroup,将多个TransformGroup对象组成单个Transform,然后就可以应该到一个UI元素的Transform属性上。
[*]MatrixTransform,创建自定义的转换,使用MatrixTransform时,可以直接操作矩阵。
 
转换和坐标系

 
转换对象时,同时还会转换对象所在的坐标空间。默认情况下,除TranslateTransform外,转换基于目标对象的坐标系的左上角(0,0)进行转换。如果想要修改转换基点,可以通过CenterX,CenterY属性进行修改。
以左上角(0,0)进行旋转,如下所示:

以矩形中心进行旋转,如下所示:

 
转换元素

 
如果想要将转换应用到控件元素(FrameworkElement),需要创建Transform并应用到FramworkElement类所提供的两个属性之一。控件所对应的两个转换属性,分别如下所示:

[*]LayoutTransform,在布局之前应用转换,布局系统处理转换之后的大小和定位。
[*]RenderTransform,修改元素外观的转换,在布局完成后应用。
将Transform应用到两个属性,都可以达到想要的效果,至于要使用哪个属性,可以根据不同场景进行区分:

[*]在对元素进行缩放,选择,或倾斜,并且需要父级元素来对元素转换后的大小进行调整是,可以使用LayoutTransform属性。
[*]如果使用动画处理后的Transform对象时,可以使用RenderTransform。并且由于RenderTransform属性提供性能优势,所以应尽可能的使用此属性。
 
旋转RotateTransform

 
默认情况下,RotateTansform围绕点(0,0)选择,如下所示:
<Border Margin="30" HorizontalAlignment="Left" VerticalAlignment="Top" BorderBrush="Black" BorderThickness="1" >
    <StackPanel Orientation="Vertical">
      <Button Content="A Button" Opacity="1" />
      <Button Content="Rotated Button">
            <Button.RenderTransform>
<Rectangle Height="50" Width="50" Fill="#CCCCCCFF" Stroke="Blue" StrokeThickness="2" Canvas.Left="100" Canvas.Top="100">
    <Rectangle.RenderTransform>
      <ScaleTransform CenterX="0" CenterY="0" ScaleX="2" ScaleY="2" />
    </Rectangle.RenderTransform>
</Rectangle><RotateTransform Angle="45" />
            </Button.RenderTransform>
      </Button>
      <Button Content="A Button" Opacity="1" />
    </StackPanel>
</Border>旋转效果,如下所示:

通过RenderTransformOrigin属性,可以设置应用旋转变换的坐标。如下所示:
<Border Margin="30" HorizontalAlignment="Left" VerticalAlignment="Top" BorderBrush="Black" BorderThickness="1" >
    <StackPanel Orientation="Vertical">
      <Button Content="A Button" Opacity="1" />
      <Button Content="Rotated Button">
            <Button.RenderTransform>
<Rectangle Height="50" Width="50" Fill="#CCCCCCFF" Stroke="Blue" StrokeThickness="2" Canvas.Left="100" Canvas.Top="100">
    <Rectangle.RenderTransform>
      <ScaleTransform CenterX="0" CenterY="0" ScaleX="2" ScaleY="2" />
    </Rectangle.RenderTransform>
</Rectangle><RotateTransform Angle="45" />
            </Button.RenderTransform>
      </Button>
      <Button Content="A Button" Opacity="1" />
    </StackPanel>
</Border>修改应用变换坐标后,如下所示:

上述RenderTransformOrigin是相对坐标,范围从(0,0)到(1,1),同样也可以通过RotateTransform的CenterX,CenterY属性进行实现相同的效果。
如果将Transform应用到LayoutTransform,则将导致影响按钮的布局,从而触发布局系统的整个处理过程。如下所示:
<Border Margin="30" HorizontalAlignment="Left" VerticalAlignment="Top" BorderBrush="Black" BorderThickness="1" >
    <StackPanel Orientation="Vertical">
      <Button Content="A Button" Opacity="1" />
      <Button Content="Rotated Button">
            <Button.RenderTransform>
<Rectangle Height="50" Width="50" Fill="#CCCCCCFF" Stroke="Blue" StrokeThickness="2" Canvas.Left="100" Canvas.Top="100">
    <Rectangle.RenderTransform>
      <ScaleTransform CenterX="0" CenterY="0" ScaleX="2" ScaleY="2" />
    </Rectangle.RenderTransform>
</Rectangle><RotateTransform Angle="45" />
            </Button.RenderTransform>
      </Button>
      <Button Content="A Button" Opacity="1" />
    </StackPanel>
</Border>应用到LayoutTransform的选择效果,如下所示:

 
缩放ScaleTransform

 
通过ScaleTransform可以对元素进行缩放,通过使用ScaleX,ScaleY属性进行缩放。这两个属性是相对值,表示缩放的倍数,小于1表示缩小,大于1表示放大,等于1表示原始大小。使用CenterX,CenterY属性指定缩放操作的中心点。
缩放示例如下所示:
<Rectangle Height="50" Width="50" Fill="#CCCCCCFF" Stroke="Blue" StrokeThickness="2" Canvas.Left="100" Canvas.Top="100">
    <Rectangle.RenderTransform>
      <ScaleTransform CenterX="0" CenterY="0" ScaleX="2" ScaleY="2" />
    </Rectangle.RenderTransform>
</Rectangle>通常,将 CenterX 和 CenterY 设置为缩放对象的中心:(Width/2、Height/2)。
<Rectangle Height="50" Width="50" Fill="#CCCCCCFF" Stroke="Blue" StrokeThickness="2" Canvas.Left="100" Canvas.Top="100">
    <Rectangle.RenderTransform>
      <ScaleTransform CenterX="0" CenterY="0" ScaleX="2" ScaleY="2" />
    </Rectangle.RenderTransform>
</Rectangle>下图显示了两个 ScaleTransform 操作之间的差异。虚线显示的是矩形在缩放之前的大小和位置。

 
倾斜扭曲SkewTransform

 
 扭曲(也称为修剪)是一种以非均匀方式拉伸坐标空间的转换。 SkewTransform 的一种典型用途是在 2D 对象中模拟 3D 深度。
SkewTransform的主要特点如下所示:

[*]使用 CenterX 和 CenterY 属性指定 SkewTransform 的中心点。
[*]使用 AngleX 和 AngleY 属性指定 x 轴和 y 轴的扭曲角度,并沿这些轴扭曲当前坐标系统。
示例:如果 AngleX 为 30,则 y 轴绕原点旋转 30 度,将 x 轴的值从该原点扭曲 30 度。 同样地,如果 AngleY 为 30,则将形状的 y 值从原点扭曲 30 度。 
以下示例向 Rectangle 应用自中心点 (0,0) 的 45 度水平扭曲。
<Rectangle Height="50" Width="50" Fill="#CCCCCCFF" Stroke="Blue" StrokeThickness="2" Canvas.Left="100" Canvas.Top="100">
    <Rectangle.RenderTransform>
      <ScaleTransform CenterX="0" CenterY="0" ScaleX="2" ScaleY="2" />
    </Rectangle.RenderTransform>
</Rectangle>以下示例向 Rectangle 应用自中心点 (25,25) 的 45 度水平扭曲。
<Rectangle Height="50" Width="50" Fill="#CCCCCCFF" Stroke="Blue" StrokeThickness="2" Canvas.Left="100" Canvas.Top="100">
    <Rectangle.RenderTransform>
      <ScaleTransform CenterX="0" CenterY="0" ScaleX="2" ScaleY="2" />
    </Rectangle.RenderTransform>
</Rectangle>以下示例向 Rectangle 应用自中心点 (25,25) 的 45 度垂直扭曲。
<Rectangle Height="50" Width="50" Fill="#CCCCCCFF" Stroke="Blue" StrokeThickness="2" Canvas.Left="100" Canvas.Top="100">
    <Rectangle.RenderTransform>
      <ScaleTransform CenterX="0" CenterY="0" ScaleX="2" ScaleY="2" />
    </Rectangle.RenderTransform>
</Rectangle>上述三个示例的效果图如下所示:

 
移动TranslateTransform

 
TranslateTransform主要用于元素的平移(移动),如将TranslateTransform应用于元素的RenderTransform属性,可以在StackPanel或DockPanel内移动元素。可以使用TranslateTransform的X属性和Y属性指定按哪个轴进行移动(单位是像素)。
以下示例使用 TranslateTransform 将元素向右移动 50 个像素,向下移动 50 个像素。
<Rectangle Height="50" Width="50" Fill="#CCCCCCFF" Stroke="Blue" StrokeThickness="2" Canvas.Left="100" Canvas.Top="100">
    <Rectangle.RenderTransform>
      <ScaleTransform CenterX="0" CenterY="0" ScaleX="2" ScaleY="2" />
    </Rectangle.RenderTransform>
</Rectangle> 
组合转换TransformGroup

 
通过TransformGroup可以将多个Transform对象合并成一个复合的Transform,并应用到元素的属性。
下面的示例使用 TransformGroup 将 ScaleTransform 和 RotateTransform 应用到 Button。
<Rectangle Height="50" Width="50" Fill="#CCCCCCFF" Stroke="Blue" StrokeThickness="2" Canvas.Left="100" Canvas.Top="100">
    <Rectangle.RenderTransform>
      <ScaleTransform CenterX="0" CenterY="0" ScaleX="2" ScaleY="2" />
    </Rectangle.RenderTransform>
</Rectangle><Rectangle Height="50" Width="50" Fill="#CCCCCCFF" Stroke="Blue" StrokeThickness="2" Canvas.Left="100" Canvas.Top="100">
    <Rectangle.RenderTransform>
      <ScaleTransform CenterX="0" CenterY="0" ScaleX="2" ScaleY="2" />
    </Rectangle.RenderTransform>
</Rectangle><Rectangle Height="50" Width="50" Fill="#CCCCCCFF" Stroke="Blue" StrokeThickness="2" Canvas.Left="100" Canvas.Top="100">
    <Rectangle.RenderTransform>
      <ScaleTransform CenterX="0" CenterY="0" ScaleX="2" ScaleY="2" />
    </Rectangle.RenderTransform>
</Rectangle>以上就是《不可不知的WPF转换(Transform)》的全部内容,旨在抛砖引玉,一起学习,共同进步。

来源:https://www.cnblogs.com/hsiang/p/18408953
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 不可不知的WPF转换(Transform)