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 月

Double 值集合)来描述。

WPF 关于变换说明:

像 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) 使您能够直接处理矩阵值,但它还提供了许多 Angle 属性即可旋转对象。

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

 

说明

示例

图示

RotateTransform

按指定的 Angle 旋转元素。

如何:旋转对象

WPF 关于变换

ScaleTransform

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

如何:缩放元素

WPF 关于变换

SkewTransform

按指定的 AngleY 量扭曲元素。

如何:使元素扭曲

WPF 关于变换

TranslateTransform

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

如何:平移元素

WPF 关于变换

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

 

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

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

 

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

下面的示例使用 FrameworkElement)旋转 45 度。下图显示了旋转的效果。

围绕点 (0,0) 旋转 45 度的矩形元素
WPF 关于变换
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) 旋转。SkewTransform 类提供 CenterX 和 CenterY 属性,可以利用这些属性来指定变换的应用点。

下一个示例也使用 RotateTransform 的中心为 (25, 25)。下图显示了旋转的效果。

围绕点 (25, 25) 旋转 45 度的矩形元素
WPF 关于变换
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 类提供的两个属性之一:

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

  • LayoutTransform 属性),您可以使性能得到优化。

应使用哪个属性?由于 LayoutTransform 属性一起使用时,这些对象似乎对元素没有影响。这是因为布局系统在处理过程中会使平移的元素回到其原始位置。

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

下面的示例使用 StackPanel 中。

默认情况下,RenderTransform 属性。下图显示了变换的效果。

从左上角沿顺时针方向旋转 45 度
WPF 关于变换
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>

下一个示例也使用 RenderTransformOrigin 属性的值与按钮的大小相关。因此,将在按钮的中心(而不是其左上角)应用旋转。下图显示了变换的效果。

围绕中心沿顺时针方向旋转 45 度
WPF 关于变换
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>

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

用于旋转按钮的 LayoutTransform
WPF 关于变换
            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 进行动画处理,请将类型兼容的动画应用于想要进行动画处理的属性。

下面的示例将 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>

有关完整示例,请参见动画概述

相关文章:

  • 2022-12-23
  • 2022-01-01
  • 2021-07-08
  • 2021-06-14
  • 2022-12-23
  • 2021-11-03
  • 2021-09-07
  • 2021-05-18
猜你喜欢
  • 2021-08-02
  • 2021-06-29
  • 2022-12-23
  • 2022-03-11
  • 2022-02-22
  • 2022-12-23
  • 2021-10-27
相关资源
相似解决方案