第十章 形状与画刷
一、形状
1、Shape常见属性
StrokeThickness:边框厚度
Stroke:边框颜色
Fill:内部填充
StrokeDashArray:实线与虚线的比例:
StrokeLineJoin:拐角轮廓
Stretch:确认如何填充可用区域
Fill:形状拉伸其宽度和高度,从而可以正好适应其容器(如果设置了明确的高度和宽度,该设置就不起作用了)
None:形状不被拉伸。除非使用Height和Width属性
Uniform:按比例改变形状的宽度和高度,直至形状到达容器边缘。如果为椭圆使用该值,最终将得到适应窗口的最大的圆。如果为矩形使用该值,将得到尽可能大的正方形
UniformFill:按比例改变形状的宽度和高度,直到形状填满了整个可用空间的高度和宽度。例如,如果在100X200单位大小的窗口中放置使用此尺寸设置的矩形,将得到200X200单位大小的矩形,并且矩形的一部分会被剪裁
2、矩形
<Rectangle Width="300" Height="400" StrokeThickness="10" Stroke="Red" StrokeLineJoin="Round" RadiusX="40" RadiusY="20" > <Rectangle.Fill> <!--图片--> Blue </Rectangle.Fill> </Rectangle>
3、椭圆与Viewbox
<Ellipse Stroke="Red" StrokeThickness="10" Stretch="Uniform"></Ellipse>
<Viewbox> <!-- 使用 Viewbox 来缩放按钮 --> <Button Content="Click Me" Width="200" Height="50" /> </Viewbox>
Viewbox 是一个非常有用的容器控件,主要用于根据其自身大小自动调整子元素的缩放比例,以保持其内容的显示效果。无论窗口如何调整大小,Viewbox 内的内容都会按比例缩放,以确保内容始终适应当前的窗口尺寸。
4、线
<Canvas> <!--两点(X1,Y1),(X2,Y2) 一线,其坐标是相对于上一级的布局容器的坐标 左负右正,上负下正 StrokeStartLineCap:设置拐角属性,可设置圆角、三角形、正方形 --> <Line Canvas.Left="100" Canvas.Top="200" StrokeThickness="10" X1="0" Y1="0" X2="100" Y2="100" StrokeDashArray="3,1" StrokeStartLineCap="Round" > <!--内部可以使用Stroke属性,添加画刷--> <Line.Stroke> <ImageBrush ImageSource="/123.png"></ImageBrush> </Line.Stroke> </Line> </Canvas>
5、折线
<Polyline Canvas.Left="200" Canvas.Top="400" Stroke="Red" StrokeThickness="20" Points="0 0,1 -100,-100 -20,-60 10" StrokeStartLineCap="Round" StrokeEndLineCap="Round" ></Polyline>
6、多边形
<Polygon Canvas.Left="90" Canvas.Top="150" Stroke="Red" StrokeThickness="20" Points="0 0,1 -100,-100 -20,-60 10"></Polygon>
二、画刷
画刷支持更改通知,因为它们继承自Freezable类。因此,如果改变了画刷,任何使用画刷的元素都会自动重新绘制自身。
画刷支持部分透明。为此,只需要修改Opacity属性,使背景能够透过前面的内容进行显示。
通过SystemBrushes类可以访问这样的画刷:此类画刷使用Windows系统设置为当前计算机定义的首选颜色。
SolidColorBrush:使用单一的连续颜色绘制区域
LinearGradientBrush:使用渐变填充绘制区域,渐变的阴影填充从一种颜色变化到另一颜色(并且,也可以在变化到第3种颜色之后再变化到第4种颜色,依此类推)
RadialGradientBrush:使用径向渐变填充绘制区域,除了是在圆形模式中从中心点向外部辐射渐变之外,这种画剧和线性渐变画剧类似
ImageBrush使用可被拉伸、缩放或平铺的图像绘制区域
DrawingBrush:使用Drawing对象绘制区域,该对象可以包含已经定义的形状和位图
VisualBrush:使用Visual对象绘制区域。因为所有WPF元素都继承自Visual类,所以可使用该画刷将部分用户界面(如按钮的表面)复制到另一个区域。当创建特殊效果时,比如部分反射效果,该画刷特别有用
BitmapCacheBrush:使用从Visual对象缓存的内容绘制区域。这种画剧和VisualBrush类似,但如果需要在多个地方重用图形内容或者频繁地重绘图形内容,这种画剧更高效
1.SolidColorBrush
最简单的画刷类型是SolidColorBrush,这种画刷填充一种固定、连续的颜色。
<Border> <Border.Background> <SolidColorBrush Color="Red" Opacity="0.3"></SolidColorBrush> </Border.Background> </Border>
画刷可以用于Foreground、Fill、Stroke等
<StackPanel> <!--<Border> <Border.Background> <SolidColorBrush Color="Red" Opacity="0.3"></SolidColorBrush> </Border.Background> </Border>--> <TextBlock Margin="20" Text="文章"> <TextBlock.Foreground> <SolidColorBrush Color="BlanchedAlmond" Opacity="0.3"></SolidColorBrush> </TextBlock.Foreground> </TextBlock> <Rectangle Height="150" Width="300" StrokeThickness="10"> <Rectangle.Fill> <SolidColorBrush Color="Cornsilk" Opacity="0.4"></SolidColorBrush> </Rectangle.Fill> <Rectangle.Stroke> <SolidColorBrush Color="PaleGreen" Opacity="0.9"></SolidColorBrush> </Rectangle.Stroke> </Rectangle> </StackPanel>
2、LinearGradientBrush
当EndPoint不为1时,可使用SpreadMethod属性进行设置:
默认为Pad填充,Reflect为镜像翻转,Repeat为复制填充
<Rectangle Width="600" Height="300"> <Rectangle.Fill> <LinearGradientBrush StartPoint="0,0" EndPoint="0,0.5" SpreadMethod="Reflect" > <!--SpreadMethod="Reflect":翻转--> <GradientStop Color="Red" Offset="0"></GradientStop> <GradientStop Color="Blue" Offset="0.5"></GradientStop> <GradientStop Color="Green" Offset="1"></GradientStop> </LinearGradientBrush> </Rectangle.Fill> </Rectangle>
3、RadialGradientBrush
<Ellipse Height="400" Width="400"> <Ellipse.Fill> <RadialGradientBrush RadiusX="0.6" RadiusY="0.6" GradientOrigin="0.7 0.3" ><!--默认0.5--> <GradientStop Color="Red" Offset="0"></GradientStop> <GradientStop Color="Blue" Offset="1"></GradientStop> </RadialGradientBrush> </Ellipse.Fill> </Ellipse>
4、ImageBrush
使用位图填充区域,可通过ImageSource指定使用的图像
Viewbox描述希望从源图像上剪裁并使用的矩形部分。前两个数值指定矩形开始的左上角,而后两个数值指定矩形的宽度和高度。Viewbox属性使用的是相对坐标系统,这一坐标系统将图像的左上角指定为(0,0),将右下角指定为(1,1)。
<Rectangle Height="300" Width="400"> <Rectangle.Fill> <!--(0.3,0.2)从图像的0.3宽度,0.2高度进行裁剪,然后填充50宽度于60%高度--> <ImageBrush ImageSource="/Image/mygo.jpg" Viewbox="0.3 0.2 0.5 0.6" ></ImageBrush> </Rectangle.Fill> </Rectangle>
ViewporeUnits可以设置平铺图像是根据绝对尺寸还是相对尺寸进行设置
Viewport设置平铺起始坐标与图像大小,前两个值为坐标 后面则为大小
<ImageBrush ImageSource="/Image/mygo.jpg" TileMode="Tile" ViewportUnits="RelativeToBoundingBox" Viewport="0 0 0.2 0.2" ></ImageBrush> </Rectangle.Fill>
其中titleMode可用于设置平铺图像的翻转方式:
Title:在可用区域复制图像
FlipX:复制图像,但是垂直翻转每个的第二列
FlipY:复制图像,但是水平翻转每个的第二行
FlipXY:复制图像,但是水平翻转每个的第二行,垂直翻转每个的第二列
5、VisualBrush
VisualBrush画刷不常用,使用这种画刷获取元素的可视化内容,并使用该内容填充任意表面。例如,可使用VisualBrush画刷将窗口中某个按钮的外观复制到同一窗口中的其他位置。然而,复制的按钮不能被单击,也不能通过任何方式与其进行交互。在此只是复制了元素的外观。
<!--仅复制外观,行为动作不被复制--> <Rectangle Height="250" Width="400"> <Rectangle.Fill> <VisualBrush Visual="{Binding ElementName=img}"></VisualBrush> </Rectangle.Fill> </Rectangle>
6、BitmapCacheBrush
VisualBrush与BitmapCacheBrush区别:
1、VisualBrush可以平铺,但是BitmapCacheBrush不行
2、若图像透明度修改,VisualBrush跟随变化,而BitmapCacheBrush不必
3、BitmapCacheBrush可调节放大倍数
<Rectangle Height="100" Width="100"> <Rectangle.Fill> <VisualBrush TileMode="Tile" Viewport="0,0,0.5,0.5" Visual="{Binding ElementName=img}"></VisualBrush> </Rectangle.Fill> </Rectangle> <!--VisualBrush类似,但是不能被平铺--> <Rectangle Height="100" Width="100"> <Rectangle.Fill> <BitmapCacheBrush Target="{Binding ElementName=img}"></BitmapCacheBrush> </Rectangle.Fill> </Rectangle>
<Rectangle Height="100" Width="100"> <Rectangle.Fill> <BitmapCacheBrush Target="{Binding ElementName=img}"> <BitmapCacheBrush.BitmapCache> <!--RenderAtScale该值指示应用于位图的缩放比例。--> <BitmapCache RenderAtScale="10"></BitmapCache> </BitmapCacheBrush.BitmapCache> </BitmapCacheBrush> </Rectangle.Fill> </Rectangle>
7、RotateTransform旋转
<Canvas> <!--RenderTransform:渲染变换--> <Rectangle Height="10" Width="80" Fill="Yellow" Stroke="Blue" Canvas.Left="100" Canvas.Top="100"/> <Rectangle Height="10" Width="80" Fill="Yellow" Stroke="Blue" Canvas.Left="100" Canvas.Top="100"> <Rectangle.RenderTransform> <!--Angle:旋转角度 CemterX/Y:中心点坐标,多使用相对坐标--> <RotateTransform Angle="25" CenterX ="45" CenterY="5"/> </Rectangle.RenderTransform> </Rectangle> <Rectangle Height="10" Width="80" Fill="Yellow" Stroke="Blue" Canvas.Left="100" Canvas.Top="100"> <Rectangle.RenderTransform> <RotateTransform Angle="50"/> </Rectangle.RenderTransform> </Rectangle> <Rectangle Height="10" Width="80" Fill="Yellow" Stroke="Blue" Canvas.Left="100" Canvas.Top="100"> <Rectangle.RenderTransform> <RotateTransform Angle="80"/> </Rectangle.RenderTransform> </Rectangle> </Canvas>
8、ScaleTransform缩放
<Rectangle Margin="50" Height="10" Width="80" Fill="Yellow" Stroke="Blue" Canvas.Left="100" Canvas.Top="100"> <Rectangle.RenderTransform> <!--ScaleX:水平方向放大,为负数时方向反向 ScaleX:垂直方向放大,为负数时方向反向 --> <ScaleTransform ScaleX="2" ScaleY="2" CenterX="0.3" CenterY="0.8"/> </Rectangle.RenderTransform> </Rectangle>
9、Opecity
Opacity属性使元素的所有内容都是部分透明的。OpacityMask属性执是供了更大的灵活性。可使元素的特定区域透明或部分透明,从而实现各种常见的的以及新颖的效果。例如,可使用 OpacityMask属性将形状逐渐褪色到完全透明。
<Button Canvas.Left="50" Canvas.Top="50" Height="30" Width="100" Content="AAAA"> <Button.OpacityMask> <LinearGradientBrush StartPoint="0,0" EndPoint="1,0"> <GradientStop Offset="0" Color="Black"></GradientStop> <GradientStop Offset="1" Color="Transparent"></GradientStop> </LinearGradientBrush> </Button.OpacityMask> </Button>
三、几何图形与图画
1、简单图像绘制
Path类提供了Data属性接受一个Geometry对象,该对象定义路径包含的一个或多个图形。
不能直接创建Geometry对象,因为Geometry是抽象类,需要使用派生类中的一个进行创建。
<StackPanel> <Path Stroke="Red" Margin="10" StrokeThickness="5" > <Path.Data> <LineGeometry StartPoint="0,0" EndPoint="100,0"></LineGeometry> </Path.Data> </Path> <Path Fill="Yellow" Margin="10" StrokeThickness="5" > <Path.Data> <!--Rect:(0,0)起始点,200,100:宽200,高100--> <RectangleGeometry Rect="0,0 200,100"></RectangleGeometry> </Path.Data> </Path> <Path Fill="Yellow" Margin="10" StrokeThickness="5" > <Path.Data> <!--RadiusX/Y:X/Y半径,Center:中心点--> <EllipseGeometry RadiusX="100" RadiusY="50" Center="400,0"></EllipseGeometry> </Path.Data> </Path> </StackPanel>
几何图形定义形状,而路径用于绘制形状。
Geometry对象为形状定义了坐标和尺寸等细节,而Path对象提供了用于绘制形
状的Stroke和Fill画刷。Path类还提供了继承自UIElement基础架构的特性,如鼠标和键盘处理。
2、GeometryGroup组合
<Path Fill="Yellow"> <Path.Data> <GeometryGroup FillRule="EvenOdd"> <RectangleGeometry Rect="0,0 100,100"></RectangleGeometry> <EllipseGeometry RadiusX="50" RadiusY="35" Center="50,50"></EllipseGeometry> </GeometryGroup> </Path.Data> </Path>
3、CombineGroup
<StackPanel> <Path Fill="Yellow" Stroke="Blue" Margin="5"> <Path.Data> <!--Union:创建包含两个几何图形所有区域的形状--> <CombinedGeometry GeometryCombineMode="Union"> <!--第一个形状--> <CombinedGeometry.Geometry1> <RectangleGeometry Rect="0,0 100,100"></RectangleGeometry> </CombinedGeometry.Geometry1> <CombinedGeometry.Geometry2> <EllipseGeometry RadiusX="65" RadiusY="35" Center="85,50"></EllipseGeometry> </CombinedGeometry.Geometry2> </CombinedGeometry> </Path.Data> </Path> <Path Fill="Yellow" Stroke="Blue" Margin="5"> <Path.Data> <!--创建包含两个几何图形共有区域的形状--> <CombinedGeometry GeometryCombineMode="Intersect"> <!--第一个形状--> <CombinedGeometry.Geometry1> <RectangleGeometry Rect="0,0 100,100"></RectangleGeometry> </CombinedGeometry.Geometry1> <CombinedGeometry.Geometry2> <EllipseGeometry RadiusX="65" RadiusY="35" Center="85,50"></EllipseGeometry> </CombinedGeometry.Geometry2> </CombinedGeometry> </Path.Data> </Path> <Path Fill="Yellow" Stroke="Blue" Margin="5"> <Path.Data> <!--创建包含两个儿何图形非共有区域的形状。换句话说,就像先合并形状(使用Union),再移除共有的部分(使用Intersect)那样--> <CombinedGeometry GeometryCombineMode="Xor"> <!--第一个形状--> <CombinedGeometry.Geometry1> <RectangleGeometry Rect="0,0 100,100"></RectangleGeometry> </CombinedGeometry.Geometry1> <CombinedGeometry.Geometry2> <EllipseGeometry RadiusX="65" RadiusY="35" Center="85,50"></EllipseGeometry> </CombinedGeometry.Geometry2> </CombinedGeometry> </Path.Data> </Path> <Path Fill="Yellow" Stroke="Blue" Margin="5"> <Path.Data> <!--创建的形状包含第一个儿何图形的所有区域,但不包含第二个几何图形的区域--> <CombinedGeometry GeometryCombineMode="Exclude"> <!--第一个形状--> <CombinedGeometry.Geometry1> <RectangleGeometry Rect="0,0 100,100"></RectangleGeometry> </CombinedGeometry.Geometry1> <CombinedGeometry.Geometry2> <EllipseGeometry RadiusX="65" RadiusY="35" Center="85,50"></EllipseGeometry> </CombinedGeometry.Geometry2> </CombinedGeometry> </Path.Data> </Path> </StackPanel>
禁止吸烟标志
<Path Fill="Yellow" Stroke="Blue"> <Path.Data> <CombinedGeometry GeometryCombineMode="Union"> <CombinedGeometry.Geometry1> <CombinedGeometry GeometryCombineMode="Exclude"> <CombinedGeometry.Geometry1> <EllipseGeometry RadiusX="50" RadiusY="50" Center="50,50"></EllipseGeometry> </CombinedGeometry.Geometry1> <CombinedGeometry.Geometry2> <EllipseGeometry RadiusX="40" RadiusY="40" Center="50,50"></EllipseGeometry> </CombinedGeometry.Geometry2> </CombinedGeometry> </CombinedGeometry.Geometry1> <CombinedGeometry.Geometry2> <RectangleGeometry Rect="44,5 10,90"> <RectangleGeometry.Transform> <RotateTransform Angle="45" CenterX="50" CenterY="50"></RotateTransform> </RectangleGeometry.Transform> </RectangleGeometry> </CombinedGeometry.Geometry2> </CombinedGeometry> </Path.Data> </Path>
4、PathGeometry绘制曲线和直线
PathGeometry是功能超级强大的图形,它能绘制其他所有几何图形能够绘制的内容,也能绘制其他所有几何图形所不能绘制的内容。它的唯一缺点是语法比较长(并且在某种程度上更加复杂)
每个PathGeometry对象都是由一个或多个PathFigure对象构建的(存储在PathGeometry.Figures集合中)。每个PathFigure对象是一系列相互连接的直线和曲线,可闭合也可不闭合。如果图形中最后一条直线的终点连接到了第一条直线的起点,那么图形就是闭合的。
<StackPanel> <!--直线--> <Path Stroke="Blue"> <Path.Data> <PathGeometry> <PathFigure StartPoint="10,100" IsClosed="True"> <LineSegment Point="100,100"></LineSegment> <LineSegment Point="100,50"></LineSegment> </PathFigure> </PathGeometry> </Path.Data> </Path> <!--曲线--> <Path Margin="20" Stroke="DarkBlue"> <Path.Data> <PathGeometry> <PathFigure StartPoint="10,100"> <!--Size代表该弧线所在椭圆的X/Y轴的半径 IsLargeArc:椭圆两个点最大的曲线 SweepDirection:翻转状态 --> <ArcSegment IsLargeArc="True" SweepDirection="Clockwise" Point="250,150" Size="100,150"></ArcSegment> </PathFigure> </PathGeometry> </Path.Data> </Path> <Path Margin="20" Stroke="DarkBlue"> <Path.Data> <PathGeometry> <PathFigure StartPoint="10,100"> <BezierSegment Point1="130,30" Point2="40,140" Point3="150,150"></BezierSegment> </PathFigure> </PathGeometry> </Path.Data> </Path> </StackPanel>
5、微语言几何图形

<Path Stroke="Blue" Data="M10,100 L100,100 L100,50 Z"></Path>
6、使用几何图形裁剪
可以裁剪图像、按钮等UIElement
<Window.Resources> <GeometryGroup x:Key="clipElip" FillRule="Nonzero"> <EllipseGeometry RadiusX="75" RadiusY="50" Center="100,150"></EllipseGeometry> <EllipseGeometry RadiusX="100" RadiusY="25" Center="200,150"></EllipseGeometry> <EllipseGeometry RadiusX="75" RadiusY="130" Center="140,140"></EllipseGeometry> </GeometryGroup> </Window.Resources> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> </Grid.ColumnDefinitions> <Button Grid.Column="2" Clip="{StaticResource clipElip}">按钮</Button> </Grid>
浙公网安备 33010602011771号