WPF转换与特效
一、Transform 转换
Transform 是 WPF 中实现2D 平面控件变换的抽象基类。它底层依靠 3×3 矩阵(Matrix) 实现坐标映射,上层提供 4 种常用变换 + 2 种组合 / 自定义变换。

通过操作矩阵值,可以旋转、缩放、倾斜和移动(转换)对象。 由于直接操作矩阵去设置旋转、缩放、倾斜和移动功能比较复杂,所以WPF提供了4个子类来设置相应的功能,后面逐个介绍。
2D转换类别
| 子类 | 说明 | 效果 | 备注 |
|---|---|---|---|
RotateTransform |
按指定的 Angle 旋转元素。 | ![]() |
表示旋转一个对象的角度 |
ScaleTransform |
按指定的 ScaleX 和 ScaleY 量缩放元素。 |
![]() |
表示放大或缩小一个对象 |
SkewTransform |
按指定的 AngleX 和 AngleY量倾斜元素。 |
![]() |
表示倾斜一个对象 |
TranslateTransform |
按指定的 X 和 Y 量移动(转换)元素。 | ![]() |
表示移动一个对象 |
TransformGroup |
将多个 TransformGroup 对象组合成单个 Transform,然后你可以应用它来转换属性。 |
||
MatrixTransform |
建其他 Transform 类不提供的自定义转换。 使用 MatrixTransform 时,可直接操作矩阵。 |
二、Transform 转换分类使用
1、RotateTransform 旋转
RotateTransform表示旋转一个对象的角度。

RotateTransform演示
xaml前端代码:
<Window x:Class="Wpf_Test.Window5"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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:Wpf_Test"mc:Ignorable="d"MouseMove="Window_MouseMove"Title="RotateTransformWindow" Height="450" Width="800"><Grid><Grid.ColumnDefinitions><ColumnDefinition/><ColumnDefinition/></Grid.ColumnDefinitions><Button Grid.Column="0"Width="100"Height="25"Content="RotateTransform"HorizontalAlignment="Center"VerticalAlignment="Center"><Button.RenderTransform><RotateTransform Angle="{Binding ElementName=slider,Path=Value}"CenterX="50" CenterY="12.5"/> <!--设置中心点--></Button.RenderTransform></Button><Button x:Name="button"Grid.Column="1"Width="100"Height="25"Content="RotateTransform"HorizontalAlignment="Center"VerticalAlignment="Center"><Button.RenderTransform><RotateTransform Angle="45"/> <!--默认值--></Button.RenderTransform></Button><Slider x:Name="slider"Grid.ColumnSpan="3"Margin="30"HorizontalAlignment="Left"VerticalAlignment="Bottom"Value="0"Maximum="720"Width="400" /></Grid>
</Window>
窗口后端代码:
private void Window_MouseMove(object sender, MouseEventArgs e)
{if (button.RenderTransform is RotateTransform rotateTransform){Point point = e.GetPosition(this);rotateTransform.Angle = point.X + point.Y;}
}
效果:

总结: 默认是左上角为旋转的中心点。可以给窗体增加鼠标移动事件,控件便会跟随鼠标进行旋转。
2、ScaleTransform 缩放
ScaleTransform表示在二维xy坐标系内缩放对象。所以它放大缩小的方向只有两个,分别是X方向和Y方向。另外,每个方向上需要设置一个中心点。

ScaleTransform演示
窗口前端代码:
<Grid><Grid.ColumnDefinitions><ColumnDefinition/><ColumnDefinition/></Grid.ColumnDefinitions><Border Width="100" Height="40" CornerRadius="10" Background="Orange"><Border.RenderTransform><ScaleTransformScaleX="{Binding ElementName=sliderX,Path=Value}"ScaleY="{Binding ElementName=sliderY,Path=Value}"/></Border.RenderTransform><TextBlock Width="100" Height="60" Padding="0,10,0,0"Text="ScaleTransform"TextAlignment="Center"/></Border><Slider x:Name="sliderX"Grid.ColumnSpan="3"Margin="40 25 20 15"HorizontalAlignment="Left"VerticalAlignment="Bottom"Value="1"Maximum="10"Width="400" /><Slider x:Name="sliderY"Orientation="Vertical"Grid.ColumnSpan="3"Margin="20"HorizontalAlignment="Left"VerticalAlignment="Bottom"Value="1"Maximum="10"Height="300" />
</Grid>
前端代码就不加事件了,如果想要加鼠标事件,与RotateTransform 类似,示例后端代码:
private void Window_MouseMove(object sender, MouseEventArgs e){if (button.RenderTransform is ScaleTransform t){Point point = e.GetPosition(this);t.ScaleX = (point.X + point.Y) / 200;t.ScaleY = (point.X + point.Y) / 200;}}
效果:

3、SkewTransform 倾斜
SkewTransform表示倾斜某个对象,它有两个方向的倾斜角度可以设置,AngleX表示设置x 轴倾斜角度,该角度是从 y 轴逆时针旋转后测量得到,单位为度。AngleY表示设置y 轴倾斜角度,该角度通过测量从 x 轴逆时针旋转得到的角度度数。另外,它也有CenterX和CenterY,表示倾斜转换中心的xy坐标。

注意:SkewTransform 可以在XY平面中为一个对象创建3维深度的错觉。
SkewTransform演示
窗口前端xaml代码:
<Grid><Grid.ColumnDefinitions><ColumnDefinition/><ColumnDefinition/><ColumnDefinition/></Grid.ColumnDefinitions><Border Grid.Column="0"Width="120"Height="120"Background="Orange"HorizontalAlignment="Center"VerticalAlignment="Center"><Border.RenderTransform><SkewTransform CenterX="0" CenterY="0"AngleX="{Binding ElementName=sliderX,Path=Value}"AngleY="{Binding ElementName=sliderY,Path=Value}"/></Border.RenderTransform></Border><Button x:Name="button"Grid.Column="1"Background="Orange"Width="120"Height="120"Content="SkewTransform倾斜"HorizontalAlignment="Center"VerticalAlignment="Center"><Button.RenderTransform><SkewTransform CenterX="60" CenterY="60"AngleX="{Binding ElementName=sliderX,Path=Value}"AngleY="{Binding ElementName=sliderY,Path=Value}"/></Button.RenderTransform></Button><Slider x:Name="sliderX"Grid.ColumnSpan="3"Margin="40 25 20 15"HorizontalAlignment="Left"VerticalAlignment="Bottom"Value="0"Maximum="180"Width="400" /><Slider x:Name="sliderY"Orientation="Vertical"Grid.ColumnSpan="3"Margin="20"HorizontalAlignment="Left"VerticalAlignment="Bottom"Value="0"Maximum="180"Height="300" />
</Grid>
效果:

可以发现,当拉动Y轴时,对象更像3维的效果。
4、TranslateTransform 平移
TranslateTransform只有X和Y两个属性,分别代表X轴和Y轴上的平移距离。

TranslateTransform演示
窗口前端代码:
<Grid><Grid.ColumnDefinitions><ColumnDefinition/><ColumnDefinition/></Grid.ColumnDefinitions><Border Grid.Column="0"Width="120"Height="120"Background="LightBlue"HorizontalAlignment="Center"VerticalAlignment="Center"><Border.RenderTransform><TranslateTransformX="{Binding ElementName=sliderX,Path=Value}"Y="{Binding ElementName=sliderY,Path=Value}"/></Border.RenderTransform></Border><Slider x:Name="sliderX"Grid.ColumnSpan="3"Margin="40 25 20 15"HorizontalAlignment="Left"VerticalAlignment="Bottom"Value="0"Maximum="180"Width="400" /><Slider x:Name="sliderY"Orientation="Vertical"Grid.ColumnSpan="3"Margin="20"HorizontalAlignment="Left"VerticalAlignment="Bottom"Value="0"Maximum="180"Height="300" />
</Grid>
效果:

可以发现为什么向上移动控件反而向下走呢?因为WPF/WinForm的坐标系是:

所以才会往下走。
5、TransformGroup 与图片查看器
TransformGroup同样继承于Transform,但是它多了一个TransformCollection类型的Children属性,表示可以将多个Transform组合成一个复合转换。复合转换就是将旋转、平移、缩放、倾斜合并起来形成一个集团转换。由于Children是一个集合,所以可以叠加多个不同的转换。

TransformGroup演示
窗口前端xaml代码:
<Grid><Canvas x:Name="canvas" Background="Transparent"MouseWheel="canvas_MouseWheel"MouseMove="canvas_MouseMove"MouseLeftButtonUp="canvas_MouseLeftButtonUp"MouseLeftButtonDown="canvas_MouseLeftButtonDown"><Image x:Name="image" Source="/Images/mm.jpg" /></Canvas></Grid>
注意,Canvas一定要设置背景颜色,不然捕捉不到鼠标事件。
后端C#代码:
public partial class Window5 : Window
{private bool isMouseDown = false;private Point mousePoint = new Point(0, 0);private TranslateTransform translateTransform = new TranslateTransform();private ScaleTransform scaleTransform = new ScaleTransform();private TransformGroup group = new TransformGroup();public Window5(){InitializeComponent();Loaded += (s, e) =>{// 将缩放和平移变换添加到TransformGroup中,并将其应用于Image控件group.Children.Add(scaleTransform);group.Children.Add(translateTransform);image.RenderTransform = group;var scale = Math.Min(canvas.ActualWidth / image.ActualWidth,canvas.ActualHeight / image.ActualHeight);scaleTransform.ScaleX = scale;scaleTransform.ScaleY = scale;translateTransform.X = (canvas.ActualWidth - image.ActualWidth * scale) / 2;};}private void canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e){isMouseDown = true;mousePoint = e.GetPosition(canvas);}private void canvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e){isMouseDown = false;}private void canvas_MouseMove(object sender, MouseEventArgs e){var position = e.GetPosition(canvas);if (isMouseDown){translateTransform.X += position.X - mousePoint.X;translateTransform.Y += position.Y - mousePoint.Y;mousePoint = position;}}private void canvas_MouseWheel(object sender, MouseWheelEventArgs e){// 获取鼠标滚轮滚动的值var delta = e.Delta;// 把滚轮值转成缩放增量double scale = delta * 0.001;// 获取鼠标在Canvas里的坐标var position = e.GetPosition(canvas);// 限制最小缩放,不能小于0.1if (scaleTransform.ScaleX + scale < 0.1) return;// 把鼠标坐标“反变换”回图片未缩放时的原始坐标Point inversePoint = group.Inverse.Transform(position);scaleTransform.ScaleX += scale;scaleTransform.ScaleY += scale;translateTransform.X = -(inversePoint.X * scaleTransform.ScaleX - position.X);translateTransform.Y = -(inversePoint.Y * scaleTransform.ScaleY - position.Y);}
}
-
第一步,定义
TransformGroup、ScaleTransform和TranslateTransform对象。 -
第二步,在初始化界面时,计算原始的图片放大倍率和平移位置。
-
第三步,在鼠标按下时设置标志位,鼠标移动时设置平移参数,鼠标滚动时计算缩放和平移,鼠标抬起时结束操作。
-
需要注意的是,进行缩放时需要拿到
TransformGroup的反函数并转换当前鼠标坐标,最后缩放结束后再设置平移位置,并再次取反。这样才能实现以鼠标坐标为中心对图片进行缩放。
效果:

总结
缩放(ScaleTransform)、旋转(RotateTransform )、平移(TranslateTransform)是用的比较多的Transform,熟悉这几个使用方式即可。同时对倾斜(SkewTransform)以及组合的TransformGroup 要有印象,看得懂。
三、特效 Effect
1、什么是 Effect
Effect = WPF 控件视觉特效基类
-
抽象类,不能直接实例化
-
给控件加阴影、模糊、自定义着色器
-
赋值给控件的
.Effect属性 -
支持动画,因为继承自
Animatable
WPF 自带两个最常用特效
-
DropShadowEffect—— 阴影 -
BlurEffect—— 模糊
2、DropShadowEffect 阴影
DropShadowEffect用于给任何控件加投影阴影,让界面有立体感。

| 属性 | 作用 |
|---|---|
| Color | 阴影颜色 |
| BlurRadius | 模糊程度(越大越朦胧) |
| ShadowDepth | 阴影距离(偏移量) |
| Direction | 阴影方向(角度,0 = 右,90 = 下,180 = 左,270 = 上) |
| Opacity | 透明度 |
简单示例:
<Grid x:Name="grid" Background="Transparent" MouseMove="Grid_MouseMove"><Button x:Name="button" Content="进入WPF中文网" Width="100" Height="50"><Button.Effect><DropShadowEffect Direction="-45"ShadowDepth="10"BlurRadius="25"Color="Gray"/></Button.Effect></Button>
</Grid>
效果:

高级示例:
private void Grid_MouseMove(object sender, MouseEventArgs e)
{double width = grid.ActualWidth;double height = grid.ActualHeight;Point centerPoint = new Point(width / 2, height / 2);Point mousePoint = e.GetPosition(grid);//与X轴的夹角double angle = Math.Atan2(mousePoint.Y - centerPoint.Y,mousePoint.X - centerPoint.X); //弧度double theta = angle * 180 / Math.PI;// 角度this.Title = $"角度={theta}";DropShadowEffect dropShadowEffect = button.Effect as DropShadowEffect;//计算距离var distance = Math.Sqrt((Math.Pow(mousePoint.X - centerPoint.X, 2)+ Math.Pow(mousePoint.Y - centerPoint.Y, 2)));dropShadowEffect.Direction = -theta;//设置阴影角度dropShadowEffect.ShadowDepth = distance / 10;//设置阴影偏移量dropShadowEffect.BlurRadius = distance / 10 * 2;//设置模糊程度
}
效果:

当鼠标在窗体内进行上下左右移动时,按钮的阴影的角度、偏移值和模糊程度都会随之而变化。
3、BlurEffect 模糊特效
让控件变模糊,常用于:
-
背景毛玻璃
-
遮罩层
-
鼠标靠近变清晰
| 属性 | 作用 |
|---|---|
| Radius | 模糊强度(0 = 不模糊,越大越糊) |
| KernelType | 获取或设置计算变得模糊的曲线 |
| RenderingBias | 性能优先 / 质量优先 |
KernelType是一个枚举类型,值为Gaussian时表示为模糊创建平滑分布的分布曲线;值为Box表示用平直分布曲线创建的简单模糊。
BlurEffect 模糊特效演示
前端xaml代码:
<Grid x:Name="grid" Background="Transparent"MouseMove="grid_MouseMove"><Ellipse x:Name="ellipse"Width="200"Height="200"><Ellipse.Effect><BlurEffect Radius="0" KernelType="Box"/></Ellipse.Effect><Ellipse.Fill><RadialGradientBrush GradientOrigin="0.25,0.25"RadiusX="0.75"RadiusY="0.75"><RadialGradientBrush.GradientStops><GradientStop Color="White" Offset="0" /><GradientStop Color="Goldenrod" Offset="0.65" /><GradientStop Color="Gray" Offset="0.8" /></RadialGradientBrush.GradientStops></RadialGradientBrush></Ellipse.Fill></Ellipse></Grid>
后端C#代码:
private void grid_MouseMove(object sender, MouseEventArgs e){double width = grid.ActualWidth;double height = grid.ActualHeight;Point centerPoint = new Point(width / 2, height / 2);Point mousePoint = e.GetPosition(grid);BlurEffect effect = ellipse.Effect as BlurEffect;//计算距离var distance = Math.Sqrt((Math.Pow(mousePoint.X - centerPoint.X, 2)+ Math.Pow(mousePoint.Y - centerPoint.Y, 2)));effect.Radius = distance / 5;//设置模糊this.Title = $"距离={distance}";}
效果:

示例2:给一个模糊图片,点击清晰按钮越来越清晰
窗口xaml代码:
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"><Image Source="/picture/11.jpg" Width="200" Height="250" Margin="0 0 0 20"><Image.Effect><BlurEffect x:Name="blurEffect" Radius="30"/></Image.Effect></Image><Button x:Name="btnClear" Content="变清晰" Margin="5" Width="100" Height="35"Background="#34C759" Foreground="White" FontSize="16" Click="BtnClear_Click"/>
</StackPanel>
后端代码:
private void BtnClear_Click(object sender, RoutedEventArgs e)
{blurEffect.Radius -= 2;
}
效果:

总结
DropShadowEffect 是最常用的特效,用来给控件增加阴影效果。BlurEffect 则是给控件增加模糊特性,重点是 Radius 属性,属性值越大越模糊。
总结
通过 Transform 转换 与 Effect 特效,可以显著增强 WPF 界面的视觉表现力与交互体验。
-
Transform 转换:实现控件的旋转、缩放、倾斜、平移等几何变换,支持组合动画,让控件实现流畅的位置、大小、角度变化,是交互动效的核心基础。
-
Effect 特效:为控件添加阴影、模糊等视觉效果,增强界面层次感、质感和美观度,可跟随鼠标动态变化,提升用户体验。
两者结合使用,能让普通界面变得生动、精致、富有现代感,大幅优化交互体验与视觉效果。




