ch10 Pens and Brushes
笔触与画刷
主要用于控制显示的颜色. Pen
用于控制边线的样式, 例如折线, 边框等. 而 Brush
用于描述填充的样式.
PENS
Pen
定义颜色与线性几何学特征. 例如折线, 曲线, 矩形或椭圆的边框等.
然后作者说明了一些一般会被认为是使用 Pen
来绘制的东西实际上是由 Brush
来绘制的, 例如文字, 实际上就是 Brush
.
Pen
的诸多属性均以 Stroke
开头.
大多数
Pen
的相关属性, 不放大仔细看, 一般都容易被忽略其不同. 然后作者例举了虚线的线帽.
Stroke
用于设置颜色, XAML 中可以使用颜色名, 也可以使用 八位/六位 16 进制数表示, 八位 16 进制数的前两位是透明度.
本章更像是对 2维绘图控件的补充
StrokeThickness
StrokeDashArray
StrokeDashCap
StrokeDashOffset
正数表示向左移动.
StrokeEndLineCap 和 StrokeStartLineCap
StrokeLineJoin
StrokeMiterLimit
该属性的目的是矫正, 避免较小的锐角出现过长的尖角.
其实这个属性的使用概念上存在很多模糊的地方.
BRUSH
描述一个区域该怎么填充. 区域可以是规范图形, 如矩形, 椭圆等; 也可以是不规范区域, 如多边形等.
填充规则
FillRule
描述怎么填充, 可取值有 Nonzero
和 EvenOdd
(奇数填充).
<Path Stroke="Blue" Data="
F0
M100,200
L700,100 700,350 200,350 200,100 400,100 400,300 100,300z
" Fill="LightGreen" StrokeThickness="5"/>
其中 F0
表示奇偶填充规则, F1
表示非零环绕原则.
<Path Stroke="Blue" Data="
F1
M100,100 L700,100 700,350 100,350z
M150,150 L650,150 650,200 150,200z
M150,250 L150,300 650,300 650,250z
"
Fill="LightGreen" StrokeThickness="5"/>
<Path Stroke="Blue" Data="
F0
M100,100 L700,100 700,350 100,350z
M150,150 L650,150 650,200 150,200z
M150,250 L150,300 650,300 650,250z
"
Fill="LightGreen" StrokeThickness="5"/>
SpreadMethod
当 Brush
的区域不足以填充绘制区域时, 用该属性描述怎么填满整个区域 (针对带有渐变等策略的填充规则). SpreadMethod
有三个取值: Pan
, Reflect
, 和 Repeat
.
Pan
, 使用最终的样式 (颜色) 填充剩余区域.Reflect
, 按照反过来的方式交替填充.Repeat
, 重复规则填充 (会出现突然变色的情况)
SolidColorBrush
SolidColorBrush
表示单个纯色. XAML 中可以使用颜色名字, 或十六进制数表示.
必要时也可以使用 SolidColorBrush
标签来构建对象.
<Ellipse>
<Ellipse.Fill>
<SolidColorBrush Color="red" />
</Ellipse.Fill>
</Ellipse>
LinearGradientBrush
线性梯度画刷
LinearGradientBrush
的属性 StartPoint
和 EndPoint
来设置开始到结束的区域范围. 取值采用 [0, 1]
的区间表示, (0,0)
表示区域的左上角, (1,1)
表示区域的右下角. 可以将 StartPoint
和 EndPoint
看成是在定义渐变的方向. 用来构成方向向量, 所以有些时候取值不是完全严苛要求的. 比如 0,0
, 1,0
和 0,1
, 1,1
含义是一样的.
LinearGradientBrush
含有一组 GradientStop
的对象, 用于定义每个梯度位置的颜色, 其 Color
属性是颜色, Offset
是在绘制范围内的位置, 取值依旧是 [0,1]
之间的数.
RadialGradientBrush
中心放射的方式来处理渐变. 定义路径与渐变范围的是圆心 GradientOrign
和距离圆心的距离 RadiusX
, RadiusY
. 坐标系依旧采用 (0,0)
到 (1,1)
的方式.
需要注意的是 1 是全部, 所以中心使用 0.5, 半径也是 0.5
TileBrush
瓦片画刷, 主打一个使用重复来填充的效果. 实际使用的是其子类: ImageBrush
, DrawingBrush
和 VisualBrush
.
ImageBrush
第3章设计工具中有详细的介绍.
基本属性
ImageSource
用于指定图片源Opacity
透明度Stretch
图片的填充方式TileMode
ImageBrush
的填充方式Viewbox
在图片上的裁剪区域, 采用左上角, 右下角坐标方式ViewboxUnits
表示裁剪使用的坐标, 相对坐标使用 0 和 1, 绝对坐标使用像素单位.Viewport
表示ImageBrush
在填充区域内的单位范围.ViewportUnits
单位.
其中 TileMode
的取值有: None
, FlipX
, FlipY
, FlipXY
, Title
.
DrawingBrush
使用 Drawing 来填充一个区域, 一个 DrawIng 可以包含 Label, Line, polygon, 甚至其他控件.
遗憾的是在 XAML 中定义一个 Drawing 是很困难的. 画刷需要包含 Drawing
属性元素来定义.
Drawing
元素可以包含 drawing 对象, 例如: GeometryDrawing
, GlyphRunDrawing
和 ImageDrawing
. 这些对象用来定义包含他们的 Drawing
属性. 例如 GeometryDrawing
对象的 Pen
和 Brush
可以应用在任何对象内的 drawing 中.
如果需要包含多个 Drawing
, 可以使用 DrawingGroup
, 它可以包含多个 Drawing
对象.
使用 DrawingBrush
来创建一个复杂的图片是件苦差事. 可能有人会下想为什么不用 ImageBrush
,那样会简单得多. 但是一旦涉及到缩放, ImageBrush
就会出现马赛克.
然后作者给出了一个案例 (随书案例) 演示了要展示一个黄色背景, 有一个鬼脸的图案. 基本结构是 DrawingBrush
的 Drawing
属性, 包含一个 DrawingGroup
, 在其中提供 GeometryDrawing
, 并设置 Pen
和 Geometry
来展示效果.
很显然, 一个及其简单的图形, 需要复杂的结构来呈现. 所以实际开发中一般是使用工具来生成对应的图片. XAML 形式如:
第三章介绍工具的时候介绍了用法.
VisualBrush
VisualBrush
控件使用用户界面元素的副本来填充一个区域. 该控件允许包含其他控件. 例如 Line
, Label
, TextBox
, Polygon
等. 也可以是你想要放到里面的任何控件.
而且如果使用 VisualBrush
来填充一个区域, 这里的控件也会根据运行时的变化而变化. 但是这个用于填充的控件无法隐藏. 但是可以利用遮盖, 或移动到不可视的区域来实现隐藏.
使用语法:
首先有一个控件(可以是自定义的)名为
ctlFace
然后可以使用:
<VisualBrush x:key="brFace" Visual="{Binding ElementName=ctlFace}"> </VisualBrush>