jk's notes
  • ch10 Pens and Brushes

ch10 Pens and Brushes

笔触与画刷

主要用于控制显示的颜色. Pen 用于控制边线的样式, 例如折线, 边框等. 而 Brush 用于描述填充的样式.

PENS

Pen 定义颜色与线性几何学特征. 例如折线, 曲线, 矩形或椭圆的边框等.

然后作者说明了一些一般会被认为是使用 Pen 来绘制的东西实际上是由 Brush 来绘制的, 例如文字, 实际上就是 Brush.

Pen 的诸多属性均以 Stroke 开头.

大多数 Pen 的相关属性, 不放大仔细看, 一般都容易被忽略其不同. 然后作者例举了虚线的线帽.

Stroke

用于设置颜色, XAML 中可以使用颜色名, 也可以使用 八位/六位 16 进制数表示, 八位 16 进制数的前两位是透明度.

本章更像是对 2维绘图控件的补充

StrokeThickness

StrokeDashArray

image-20250625164355626

StrokeDashCap

image-20250625164414363

StrokeDashOffset

image-20250625164447364

正数表示向左移动.

StrokeEndLineCap 和 StrokeStartLineCap

image-20250625164546430

StrokeLineJoin

image-20250625164608249

StrokeMiterLimit

该属性的目的是矫正, 避免较小的锐角出现过长的尖角.

image-20250625165137389

其实这个属性的使用概念上存在很多模糊的地方.

BRUSH

描述一个区域该怎么填充. 区域可以是规范图形, 如矩形, 椭圆等; 也可以是不规范区域, 如多边形等.

填充规则

FillRule 描述怎么填充, 可取值有 Nonzero 和 EvenOdd (奇数填充).

image-20250625165559401

<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"/>

image-20250625171516114

其中 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"/>

image-20250625172421606

<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"/>

image-20250625172451278

SpreadMethod

当 Brush 的区域不足以填充绘制区域时, 用该属性描述怎么填满整个区域 (针对带有渐变等策略的填充规则). SpreadMethod 有三个取值: Pan, Reflect, 和 Repeat.

  • Pan, 使用最终的样式 (颜色) 填充剩余区域.
  • Reflect, 按照反过来的方式交替填充.
  • Repeat, 重复规则填充 (会出现突然变色的情况)

image-20250625173025914

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.

image-20250625181735297

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 形式如:

image-20250718163451386第三章介绍工具的时候介绍了用法.

VisualBrush

VisualBrush 控件使用用户界面元素的副本来填充一个区域. 该控件允许包含其他控件. 例如 Line, Label, TextBox, Polygon 等. 也可以是你想要放到里面的任何控件.

而且如果使用 VisualBrush 来填充一个区域, 这里的控件也会根据运行时的变化而变化. 但是这个用于填充的控件无法隐藏. 但是可以利用遮盖, 或移动到不可视的区域来实现隐藏.

使用语法:

  • 首先有一个控件(可以是自定义的)名为 ctlFace

  • 然后可以使用:

    <VisualBrush x:key="brFace"
                 Visual="{Binding ElementName=ctlFace}">
    </VisualBrush>
    

小结

Last Updated:
Contributors: jk