• WPF 关于变换


    1、使用Canvas作为容器,子元素(如Image)的RenderTransformOrigin设置为(0.5,0.5),但是,在执行变换时并非以其中心点来变换。

    如在后台代码中处理:

    var element = e.Source as FrameworkElement;
    //element.RenderTransformOrigin = new Point(0.5, 0.5);
    Matrix matrix = (element.RenderTransform as MatrixTransform).Matrix;
    //var centerX=element.ActualWidth/2;
    //var centerY=element.ActualHeight/2;
    //matrix.ScaleAt(scale, scale, centerX, centerY);
    matrix.Scale(scale, scale);
    matrix.Translate(e.DeltaManipulation.Translation.X, e.DeltaManipulation.Translation.Y);//对于移动变换中心点无关紧要
    matrix.Rotate(e.DeltaManipulation.Rotation); //matrix.RotateAt(e.DeltaManipulation.Rotation, centerX, centerY);

     无论是在xaml中设置RenderTransformOrigin还是后台处理,都不能以中心点来变换。

    2、使用Grid作为容器,则可达到目的。

    查了许久,只是大概找到原因是Canvas与Gird处理子元素的变换时换算公式不同。但具体公式没有找到,如果有哪位大大知道还请告知。

    MSDN上对于变换的说明:

    变换概述

    更新:2007 年 11 月

    本主题描述如何使用 二维 Transform 类来旋转、按比例缩放、移动(平移)和扭曲 FrameworkElement 对象。

    本主题包括下列各节。

    Transform 定义如何将一个坐标空间中的点映射或变换到另一个坐标空间。此映射由变换 Matrix(一个三行三列的 Double 值集合)来描述。

    说明:

    像 Microsoft 一样,Windows Presentation Foundation (WPF) 也使用行优先矩阵。矢量用行矢量(而不是列矢量)表示。

    下表显示了 WPF 矩阵的结构。

    二维变换矩阵

    M11

    默认值:1.0

    M12

    默认值:0.0

    0.0

    M21

    默认值:0.0

    M22

    默认值:1.0

    0.0

    OffsetX

    默认值:0.0

    OffsetY

    默认值:0.0

    1.0

    通过处理矩阵值,您可以旋转、按比例缩放、扭曲和移动(平移)对象。例如,如果将第三行第一列中的值(OffsetX 值)更改为 100,则可以使用它将对象沿 x 轴移动 100 个单位。如果将第二行第二列中的值更改为 3,您可以使用它将对象拉伸为其当前高度的三倍。如果同时更改两个值,则可将对象沿 x 轴移动 100 个单位并将其高度拉伸 3 倍。由于 Windows Presentation Foundation (WPF) 仅支持仿射变换,因此右边列中的值始终为 0、0、1。

    尽管 Windows Presentation Foundation (WPF) 使您能够直接处理矩阵值,但它还提供了许多 Transform 类,您可以使用这些类来变换对象,而无需了解基础矩阵结构的配置方式。例如,利用 ScaleTransform 类,您可以通过设置对象的 ScaleXScaleY 属性来按比例缩放对象,而不用处理变换矩阵。同样,利用 RotateTransform 类,您只需通过设置对象的 Angle 属性即可旋转对象。

    Windows Presentation Foundation (WPF) 为常见变换操作提供了以下 二维 Transform 类:

     

    说明

    示例

    图示

    RotateTransform

    按指定的 Angle 旋转元素。

    如何:旋转对象

    旋转图

    ScaleTransform

    按指定的 ScaleXScaleY 量按比例缩放元素。

    如何:缩放元素

    缩放图

    SkewTransform

    按指定的 AngleXAngleY 量扭曲元素。

    如何:使元素扭曲

    扭曲图

    TranslateTransform

    按指定的 XY 量移动(平移)元素。

    如何:平移元素

    平移图

    为了创建更复杂的变换,Windows Presentation Foundation (WPF) 提供了如下两个类:

     

    说明

    示例

    TransformGroup

    将多个 TransformGroup 对象组合为可以随后应用于变换属性的单一 Transform

    如何:向对象应用多个变换

    MatrixTransform

    创建其他 Transform 类未提供的自定义变换。在使用 MatrixTransform 时,将直接处理矩阵。

    如何:使用 MatrixTransform 创建自定义变换

    Windows Presentation Foundation (WPF) 也提供 三维 变换。有关更多信息,请参见 Transform3D 类。

    变换对象的一种方法是声明适当的 Transform 类型,并将其应用于对象的变换属性。不同类型的对象具有不同类型的变换属性。下表列出了若干常用的 Windows Presentation Foundation (WPF) 类型及其变换属性。

     

    在变换对象时,您不仅仅是变换对象,您变换的是对象所在的坐标系。默认情况下,变换将以目标对象坐标系的原点 (0,0) 为中心进行。唯一的例外是 TranslateTransformTranslateTransform 没有要设置的中心属性,因为不管以何处为中心,平移效果都相同。

    下面的示例使用 RotateTransform,围绕其默认中心 (0, 0) 将 Rectangle 元素(一种 FrameworkElement)旋转 45 度。下图显示了旋转的效果。

    围绕点 (0,0) 旋转 45 度的矩形元素
    围绕 (0,0) 旋转 45 度的 FrameworkElement
    XAML        
    <Canvas Width="200" Height="200">
      <Rectangle 
        Canvas.Left="100" Canvas.Top="100"
        Width="50" Height="50" 
        Fill="RoyalBlue" Opacity="1.0">
        <Rectangle.RenderTransform>
          <RotateTransform Angle="45" />
        </Rectangle.RenderTransform>
      </Rectangle>
    </Canvas>
    

    默认情况下,元素将围绕其左上角 (0, 0) 旋转。RotateTransformScaleTransformSkewTransform 类提供 CenterX 和 CenterY 属性,可以利用这些属性来指定变换的应用点。

    下一个示例也使用 RotateTransformRectangle 元素旋转 45 度;但是,这一次设置了 CenterXCenterY 属性,因此 RotateTransform 的中心为 (25, 25)。下图显示了旋转的效果。

    围绕点 (25, 25) 旋转 45 度的矩形元素
    围绕 (25, 25) 旋转 45 度的 Geometry
    XAML        
    <Canvas Width="200" Height="200">
      <Rectangle 
        Canvas.Left="100" Canvas.Top="100"
        Width="50" Height="50" 
        Fill="RoyalBlue" Opacity="1.0">
        <Rectangle.RenderTransform>
          <RotateTransform Angle="45" CenterX="25" CenterY="25" />
        </Rectangle.RenderTransform>
      </Rectangle>
    </Canvas>
    

    若要将变换应用于 FrameworkElement,请创建 Transform 并将其应用于 FrameworkElement 类提供的两个属性之一:

    • LayoutTransform — 在布局处理过程之前应用的变换。应用了变换后,布局系统将处理元素的变换后大小和位置。

    • RenderTransform — 修改元素的外观但在布局处理过程完成之后应用的变换。通过使用 RenderTransform 属性(而不是 LayoutTransform 属性),您可以使性能得到优化。

    应使用哪个属性?由于 RenderTransform 属性能够使性能得到优化,因此请尽可能使用该属性,特别是在使用带有动画效果的 Transform 对象时。在按比例缩放、旋转或扭曲时使用 LayoutTransform 属性,并且,您需要元素的父项适应元素的变换后大小。请注意,将 TranslateTransform 对象与 LayoutTransform 属性一起使用时,这些对象似乎对元素没有影响。这是因为布局系统在处理过程中会使平移的元素回到其原始位置。

    有关 Windows Presentation Foundation (WPF) 中的布局的附加信息,请参见布局系统概述。

    下面的示例使用 RotateTransform 将按钮沿顺时针方向旋转 45 度。该按钮包含在具有两个其他按钮的 StackPanel 中。

    默认情况下,RotateTransform 围绕点 (0, 0) 旋转。由于示例未指定中心值,因此按钮将围绕点 (0, 0)(即按钮的左上角)旋转。RotateTransform 应用于 RenderTransform 属性。下图显示了变换的效果。

    从左上角沿顺时针方向旋转 45 度
    使用 RenderTransform 变换的按钮
    XAML        
    <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>
            <RotateTransform Angle="45" />
          </Button.RenderTransform>
        </Button>
        <Button Content="A Button" Opacity="1" />
      </StackPanel>
    </Border>
    

    下一个示例也使用 RotateTransform 将按钮沿顺时针方向旋转 45 度,但它同时将按钮的 RenderTransformOrigin 设置为 (0.5, 0.5)。RenderTransformOrigin 属性的值与按钮的大小相关。因此,将在按钮的中心(而不是其左上角)应用旋转。下图显示了变换的效果。

    围绕中心沿顺时针方向旋转 45 度
    围绕中心变换的按钮
    XAML        
    <Border Margin="30"   
      HorizontalAlignment="Left" VerticalAlignment="Top"
      BorderBrush="Black" BorderThickness="1">
      <StackPanel Orientation="Vertical">
        <Button Content="A Button" Opacity="1" />
        <Button Content="Rotated Button"
          RenderTransformOrigin="0.5,0.5">
          <Button.RenderTransform>
            <RotateTransform Angle="45" />
          </Button.RenderTransform>
        </Button>
        <Button Content="A Button" Opacity="1" />
      </StackPanel>
    </Border>
    

    下面的示例使用 LayoutTransform 属性(而不是 RenderTransform 属性)来旋转按钮。这样会使变换影响按钮的布局,从而触发布局系统的全面处理过程。因此,将会旋转按钮,然后重新定位按钮,因为按钮大小发生了变化。下图显示了变换的效果。

    用于旋转按钮的 LayoutTransform
    使用 LayoutTransform 变换的按钮
                XAML        
    <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.LayoutTransform>
            <RotateTransform Angle="45"  />
          </Button.LayoutTransform>
        </Button>   
        <Button Content="A Button" Opacity="1" />
      </StackPanel>
    </Border>
    

    由于 Transform 类继承自 Animatable 类,因此可以对它们进行动画处理。若要对 Transform 进行动画处理,请将类型兼容的动画应用于想要进行动画处理的属性。

    下面的示例将 StoryboardDoubleAnimationRotateTransform 一起使用,以便在单击 Button 时使其旋转到位。

    XAML        
    <Page 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Title="Button Animated RotateTransform Example"
      Background="White" Margin="50">
      <StackPanel>
    
    
    
        <Button Content="A Button"
          RenderTransformOrigin="0.5,0.5">
          <Button.RenderTransform>
            <RotateTransform x:Name="AnimatedRotateTransform" Angle="0" />
          </Button.RenderTransform>
          <Button.Triggers>
            <EventTrigger RoutedEvent="Button.Click">
              <BeginStoryboard>
                <Storyboard>
                  <DoubleAnimation 
                    Storyboard.TargetName="AnimatedRotateTransform"
                    Storyboard.TargetProperty="Angle" 
                    To="360" Duration="0:0:1" FillBehavior="Stop" />
                </Storyboard>
              </BeginStoryboard>
            </EventTrigger>
          </Button.Triggers>
        </Button>
    
      </StackPanel>
    </Page>
    

    有关完整示例,请参见二维转换示例。有关动画的更多信息,请参见动画概述

    由于 Transform 类继承自 Freezable 类,因此它提供了多种特殊功能:Transform 对象可声明为资源、在多个对象之间共享、设为只读以提高性能、进行克隆以及设为线程安全。有关 Freezable 对象提供的不同功能的更多信息,请参见 Freezable 对象概述

  • 相关阅读:
    对double数据类型的数据保留两位小数,并且进行四舍五入
    div位置设置
    每天一算法 -- (排序算法总结)
    SQL行转列
    设计模式的六大原则
    每天一算法 -- (插入排序)
    每天一算法 -- (选择排序)
    通用扩展函数--类型转换
    wcf和webservice
    Cookie的介绍及使用
  • 原文地址:https://www.cnblogs.com/LCHL/p/3067156.html
Copyright © 2020-2023  润新知