1、理解形状。
在WPF用户界面中,绘制2D内容的最简单的方式是使用形状(shape),专门用于绘制一些简单的直线、椭圆、矩形和一些多边形。shape(形状)继承自FrameworkElement类,因此形状是元素。分析一下下图的继承关系。
2、Shape类常用的一些属性。
由上图可得出,只有很少一部分类继承自Shape类,Shape类常用属性如下:
Shape类常用属性 | |
名称 | 说明 |
Fill | 设置绘制形状表面(边框内的所有内容)的画刷对象 |
Stroke | 设置绘制形状边缘(边框)的画刷对象。 |
StrokeThickness | 像素对齐 |
StrokeStartLineCap StrokeEndLineCap | 决定直线开始端和结束端边缘的轮廓,只影响Line和Polyline |
Streach | 确定形状如何填充可用的区域 |
3、椭圆和矩形。
椭圆和矩形是一个简单的形状,如果使用举行需要为其设置Height属性、Width属性、Fill属性和Stroke属性(如果不设置Fill属性和Stroke属性,形状就不会显示)。其中Rectangle类增加了两个额外的属性,RadiusX属性和RadiusY属性(用于设置圆形拐角)。
<StackPanel HorizontalAlignment="Stretch">
<!--通过Ellipse创建一个椭圆-->
<Ellipse Width="200" Height="100" Stroke="Yellow" Fill="Beige"></Ellipse>
<!--通过Rectangle创建一个矩形-->
<Rectangle Width="200" Height="100" Stroke="Yellow" Fill="Beige" RadiusX="10" RadiusY="10" Stretch="None"></Rectangle>
</StackPanel>
Streach枚举值。
Streach常用枚举值 | |
名称 | 说明 |
Fill | 形状拉伸其高度和宽度,从而适应其容器(如果设置了宽度和高度,该设置就不起作用了) |
None | 形状不被拉伸,除非使用width和height属性,否则不显示形状 |
Unifom | 按比例改变形状的宽度和高度,直至形状达到容器边缘 |
UniformToFill | 按比例改变形状的宽度和高度,直到形状填满了整个可用空间的高度和宽度,如果在100×200单位大小的窗口中放置使用此尺寸设置的矩形,将得到200×200单位大小的矩形,且举行的一部分会被裁剪掉。 |
4、直线(Line)。
Line形状表示连接一个点和另一个点的一条直线,起点和终点由4个属性设置:X1与Y1(用于第一个点),X2与Y2(用于第2个点)。使用Line,必须要使用Stroke属性设置颜色,使用Fill属性设置颜色无效。
<Line X1="0" Y1="0" X2="100" Y2="100" Stroke="Red" ></Line>
5、折线(Polyline)。
可以通过Polyline类绘制一系列相互连接的直线,只需要使用Points属性提供一系列 X 和 Y 坐标,在每个坐标之间添加空格和逗号。
<Polyline Stroke="Blue" Points="0 0,100 100,50 30,300 250"></Polyline>
分析:从0 0(x轴=0,y轴=0)----->100 100(x轴=100,y轴=100)----->50 30(x轴=50,y轴=30)----->300 250(x轴=300,y轴=250)
6、多边形(Polygon)。
Polygon和Polyline类一样,Polygon类也包含一系列坐标的Points集合,唯一的区别是Polygon形状添加最后一条线段,将最后一个点连接到开始点,用Fill画刷填充图形。
<Polygon Stroke="Red" Points="0 0,100 100,50 30,300 250" Fill="Red"></Polygon>
7、直线线帽和直线交点。
当绘制Line和Polyline形状时,可使用StrokeStartLineCap和StrokeEndLineCap属性选择如何绘制直线的开始端和结束端,StrokeStartLineCap和StrokeEndLineCap属性有4个属性值,分别是:Flat(默认的,直线在最后坐标处立即终止)、Round(平滑地绘制拐角)。
StrokeStartLineCap和StrokeEndLineCap属性值 | |
属性值 | 说明 |
Flat | 默认的,直线在最后坐标处立即终止 |
Round | 平滑地设置拐角 |
Square | 直线端点具有尖锐边缘 |
Triggle | 具有尖锐边缘 |
StrokeLineJoin(扭曲拐角)属性值 | |
属性值 | 说明 |
Miter | 使用尖锐的边缘 |
Bevel | 切掉边缘 |
Round | 平滑过渡边缘 |
8、点划线。
可以通过StrokeDashArray属性为先设置点划线(根据指定模式使用空白断开的直线)。
<!--StrokeDashArray="4 5" 其中数字4是线段的长度,数字5是空白的长处-->
<Polyline Points="0 0,100 100,300 100,100 200" Stroke="Red" StrokeDashArray="4 5"></Polyline>
9、像素对齐。
通过UIElement类的SnapsToDeVicePixels属性设置为true即可,解决锯齿现象。
10、画刷。
画刷填充区域,不管是元素的背景色、前景色和边框,都需要用到画刷,最简单的画刷类型是SolidColorBrush,继承自System.Windows.Media.Brush类。继承自System.Windows.Media.Brush类的常用画刷类如下:
画刷类 | |
名称 | 说明 |
SolidColorBrush | 使用单一的连续颜色绘制区域 |
LinearGradientBrush | 使用渐变填充绘制区域,渐变的阴影填充从一种颜色到另一种颜色 |
RadialGradientBrush | 使用径向渐变填充绘制区域(一般用于圆形模式中从中心点向外部渐变) |
ImageBrush | 使用可被拉伸,缩放或者平铺的图像绘制区域 |
DrawingBrush | 使用Drawing对象绘制区域,该对象可以包含已经定义的形状和位图 |
VisualBrush | 使用Visual对象绘制区域。 |
BitmapCacheBrush | 使用从Visual对象缓存的内容绘制区域。 |
11、SolidColorBrush画刷。
一般情况下,如果设置元素的Foreground(前景色)和Background(背景色)。
xaml代码:
<Button Height="50" FontSize="30" MouseEnter="Button_MouseEnter">Hello,World!!!</Button>
后台代码:
private void Button_MouseEnter(object sender, MouseEventArgs e)
{
Button btn = (Button)sender;
//设置前景色。
btn.Foreground = new SolidColorBrush(Colors.Blue);
//设置背景色。
btn.Background = new SolidColorBrush(Color.FromRgb(0, 255, 0));
}
12)、LinearGradientBrush(线性渐变画刷)画刷。
通过LinearGradientBrush画刷创建从一种颜色变化到另一种颜色的混合模式。使用LinearGradientBrush对象时,需要使用GradientStop属性和Offset属性。其中通过GradientStop对象设置颜色,通过Offset属性设置偏移值。可在所有使用SolidColorBrush的地方使用LinearGradientBrush画刷。
Xaml代码:
<StackPanel>
<!--为矩形设置-->
<Rectangle Width="230" Height="150">
<Rectangle.Fill>
<!--创建LinearGradientBrush对象用于填充Fill属性-->
<LinearGradientBrush>
<!--通过添加GradientStop对象设置颜色并设置偏移量-->
<GradientStop Color="Red" Offset="0"></GradientStop>
<GradientStop Color="Green" Offset="1"></GradientStop>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<!--为Button设置背景色-->
<Button Width="230" Height="150">
<Button.Background>
<LinearGradientBrush>
<GradientStop Color="Red" Offset="0"></GradientStop>
<GradientStop Color="Yellow" Offset="1"></GradientStop>
</LinearGradientBrush>
</Button.Background>
</Button>
</StackPanel>
效果图:
根据上图可看出,渐变色是从左上角到右下角的方向的过度。 可以使用LinearGradientBrush对象的StartPoint和EndPoint属性控制渐变方向。一般左上角坐标是(0,0),右下角坐标是(1,1),而不管该区域实际上有多宽和多高。各个角落坐标点如下:
10.3)、RadialGradientBrush(径向渐变画刷)画刷。
RadialGradientBrush画刷和LinearGradientBrush画刷的工作方式类似,也使用一系列具有不同偏移值的颜色,为指定第一种颜色在渐变中的开始点,需要使用GradientOrigion属性,默认情况下,渐变的开始点是(0.5,0.5),该点表示区域的中心。与LinearGradientBrush画刷一样,RadialGradientBrush也使用比例坐标系统,该坐标系统将(0,0)作为左上角坐标,将(1,1)作为右下角坐标。
Xaml代码:
<Ellipse Width="300" Height="300">
<Ellipse.Fill>
<!--创建一个RadialGradientBrush对象-->
<RadialGradientBrush>
<!--设置颜色和坐标-->
<GradientStop Color="Red" Offset="0"></GradientStop>
<GradientStop Color="Yellow" Offset="0.25"></GradientStop>
<GradientStop Color="Pink" Offset="0.5"></GradientStop>
<GradientStop Color="Blue" Offset="0.75"></GradientStop>
<GradientStop Color="Gainsboro" Offset="1"></GradientStop>
</RadialGradientBrush>
</Ellipse.Fill>
</Ellipse>
效果图:
13、ImageBrush画刷。
可以使用ImageBrush画刷用位图填充区域。ImageBrush有4个非常重要的属性,分别是:ImageSource属性(为其指定图片来源)、ViewBox属性(用于设置图片中的内容和尺寸,可以根据坐标放大一块内容),ViewportUnits属性和TileMode属性。
在xaml中定义一个简单的背景图:
<Button>
<Button.Background>
<!-- 创建一个画刷,通过ImageSource为其指定一个图片路径 -->
<ImageBrush ImageSource="1.jpg"></ImageBrush>
</Button.Background>
</Button>
效果图:
13.1)、VIewBox属性。
ViewBox属性(用于设置图片中的内容和尺寸,可以根据坐标放大一块内容)。
13.2)、平铺的ImageBrush画刷。
平铺对象时,通常有两种选择,分别是按比例平铺和按尺寸平铺两种方式。一般常配合着Viewport属性、ViewportUnits和TileMode属性,这3个属性决定了平铺图像的尺寸和排列方式。其中ViewPort用于设置每幅图像的尺寸,
按比例平铺:填充区域始终具有相同数量的平铺对象,为适应填充区域,平铺的图像会扩展或收缩。
按固定尺寸平铺:平铺图像始终具有相同的尺寸,填充区域的尺寸决定了显示的平铺图像的数量。
14、变换。
通过使用变换(transform),许多绘图任务将更趋势简单,变换是通过不加通知地切换形状或元素使用的坐标系统来改变形状或元素绘制方式的对象。变换继承自System.Windows.Media.Transform抽象类的类表示。
变换类(Transform) | ||
名称 | 说明 | 重要属性 |
TranslateTransform | 将坐标移动一段距离,如果希望在不同地方绘制相同的形状,会非常有用。 | X、Y |
RotateTransform | 旋转坐标系统,正常绘制的形状绕着选择的中心点旋转。 | Angle、CenterX、CenterY |
ScaleTransform | 放大或缩小坐标系统,从而绘制更大或更小的图形。 | AngleX、AngleY、CenterX、CenterY |
SkewTransform | 通过倾斜一定角度扭曲坐标系统,如绘制正方形矩形,通过倾斜会变成平行四边形。 | AngleX、AngleY、CenterX、CenterY |
MatrixTransform | 使用提供的矩阵的乘机修改坐标系统 | Matrix |
TransformGroup | 组合多个变换,从而一次可以应用所有变换,应用变化的顺序挺重要 | |
15、变化形状。
为变换形状,将RenderTransform属性指定为希望使用的变换对象,还可以LayoutTransform属性。
15.1)、RotateTransform。
有3个重要的属性,分别是:Angle(顺时针旋转角度)、CenterX(旋转中心点的X坐标)和CenterY(旋转中心点的Y坐标)。CenterX和CenterY是绝对坐标定位,而可以根据RenderTransformOrigion设置相对定位。
<StackPanel>
<Rectangle Stroke="Red" Fill="Red" Width="250" Height="30">
<!--通过RenderTransform属性-->
<Rectangle.RenderTransform>
<!--通过旋转类RotateTransform,然后设置Angle属性设置旋转角度-->
<RotateTransform Angle="30"></RotateTransform>
</Rectangle.RenderTransform>
</Rectangle>
<Button Width="250" Height="80" Content="Hello,World!!!" FontSize="20">
<Button.LayoutTransform>
<RotateTransform Angle="30"></RotateTransform>
</Button.LayoutTransform>
</Button>
</StackPanel>
15.2)、ScaleTransform。
常用属性有:ScaleX属性和ScaleY属性。其中,将ScaleX = 2 的意思是将元素的宽放大1倍,将ScaleY = 2的意思是将元素的高放大1倍。如果是负数,就缩小。
<Button Name="btn1" Width="100" Height="50" Content="test">
<Button.RenderTransform>
<!--将button的宽和高都放大1倍-->
<ScaleTransform ScaleX="2" ScaleY="2"></ScaleTransform>
</Button.RenderTransform>
</Button>
15.3)、TransformGroup。
如果要为元素同时设置ScaleTransform属性和RotateTransform属性时,那么,就要使用TransformGroup了。在TransformGroup中放置ScaleTransform和RotateTransform。
<Button Name="btn1" Width="100" Height="50" Content="test">
<Button.RenderTransform>
<!--在TransformGroup中放置ScaleTransform和RotateTransform-->
<TransformGroup>
<ScaleTransform ScaleX="2" ScaleY="2"></ScaleTransform>
<RotateTransform Angle="20"></RotateTransform>
</TransformGroup>
</Button.RenderTransform>
</Button>
后台写:
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
//伪元素设置RotateTransform属性。
////声明一个RotateTransform对象。
//RotateTransform rtf = new RotateTransform(30);
////设置RenderTransformOrigin属性。
//btn1.RenderTransformOrigin = new Point(0.5, 0.5);
////将元素的RenderTransform属性赋值为声明的RotateTransform对象。
//btn1.RenderTransform = rtf;
//为元素设置ScaleTransform属性。
////声明ScaleTransform对象。
//ScaleTransform stf = new ScaleTransform();
////设置ScaleX属性。
//stf.ScaleX = 2;
////设置ScaleY属性。
//stf.ScaleY = 2;
////设置元素的RenderTransformOrigin属性。
//btn1.RenderTransformOrigin = new Point(0.5, 0.5);
////为元素的RenderTransform属性赋值。
//btn1.RenderTransform = stf;
//为元素设置RotateTransform属性和ScaleTransform属性。
//声明TransformGroup对象。
TransformGroup tfg = new TransformGroup();
//声明TransformGroup杜对象。
RotateTransform rtf = new RotateTransform(30);
//将RotateTransform对象加入到TransformGroup对象中。
tfg.Children.Add(rtf);
//声明ScaleTransform对象。
ScaleTransform stf = new ScaleTransform();
//设置ScaleX属性。
stf.ScaleX = 2;
//设置ScaleY属性。
stf.ScaleY = 2;
//将ScaleTransform对象加入到TransformGroup中。
tfg.Children.Add(stf);
btn1.RenderTransformOrigin = new Point(0.5, 0.5);
//为元素的RenderTransform属性赋值为TransformGroup对象(TransformGroup对象中有ScaleTransform对象和RotateTransform对象)。
btn1.RenderTransform = tfg;
}
End!