- UI组件
- 桌面应用
【免费下载链接】HandyControl
Contains some simple and commonly used WPF controls
本文档(doc/source/handycontrol/tools/hatchBrushGenerator/index.md)配套讲解 HandyControl 的阴影画笔生成器(HatchBrushGenerator):它如何以一行代码生成 50 多种位图阴影图案画刷,并保持与 WinFormsSystem.Drawing.Drawing2D.HatchBrush一致的外观行为。读完本文,你将掌握生成器的调用方式、HatchStyle枚举全貌、底层DrawingBrush实现原理,以及在 XAML/MVVM 中的集成方案,可直接用于图表背景、编辑器纹理、报表填充、图像水印等场景。
一、HatchBrushGenerator 是什么
在 WPF 中,原生控件体系并没有直接对应 WinFormsHatchBrush的阴影画刷类型。HandyControl 在 HatchBrushGenerator.cs 中实现了这一能力:HC 提供了 50 多种不同图案的阴影样式,其行为与 WinForms 中的表现一致。
它的核心职责非常单一——给定一个HatchStyle枚举、一个前景色和一个背景色,返回一个可直接赋值给Fill、Background等属性的DrawingBrush。由于返回类型是 WPF 标准画刷类型,它可以在不引入任何额外依赖的情况下,无缝替换SolidColorBrush、LinearGradientBrush等常规画刷。
二、基础用法:三步拿到阴影画刷
根据文档中的案例,使用过程只需两步:
第一步:创建阴影画笔生成器实例
var brushGenerator = new HatchBrushGenerator();第二步:调用GetHatchBrush方法,传入HatchStyle枚举、前景色、背景色,即可返回一个DrawingBrush画刷:
var brush = brushGenerator.GetHatchBrush(HatchStyle.Horizontal, 前景色, 背景色);其中三个参数的完整含义如下:
| 参数 | 类型 | 说明 |
|---|---|---|
hatchStyle | HandyControl.Data.HatchStyle | 阴影图案样式,共 53 个枚举值(详见第三节) |
foreColor | System.Windows.Media.Color | 前景色,决定图案线条/点阵本身的颜色 |
backColor | System.Windows.Media.Color | 背景色,决定图案底衬区域的颜色 |
返回值为System.Windows.Media.Brush(实际是DrawingBrush),可直接用于 WPF 任意接受Brush的属性。例如:
// 将一个以深蓝线条、浅灰底衬的"十字交叉"图案填充到矩形上 var rect = new Rectangle { Width = 200, Height = 120, Fill = new HatchBrushGenerator().GetHatchBrush( HatchStyle.Cross, Color.FromRgb(0x1E, 0x3A, 0x5F), Color.FromRgb(0xE8, 0xEE, 0xF5)) };三、HatchStyle 枚举全览:53 种阴影图案
HatchStyle枚举定义于 HatchStyle.cs,共 53 个成员,与源码中HatchBrushes位图表(53 组 8×8 位数据)一一对应。按图案特征可归为以下几类:
基础直线类
| 枚举值 | 图案描述 |
|---|---|
Horizontal/Vertical | 水平线 / 垂直线 |
ForwardDiagonal/BackwardDiagonal | 前向(左上到右下)/ 后向(右上到左下)斜线 |
Cross/DiagonalCross | 十字交叉 / 斜线交叉 |
密度百分比类(点阵填充密度)
Percent05、Percent10、Percent20、Percent25、Percent30、Percent40、Percent50、Percent60、Percent70、Percent75、Percent80、Percent90——数字即表示前景点阵覆盖的近似密度百分比,可用于灰度纹理的视觉分级。
方向与粗细变体类
LightDownwardDiagonal、LightUpwardDiagonal、DarkDownwardDiagonal、DarkUpwardDiagonal、WideDownwardDiagonal、WideUpwardDiagonal、LightVertical、LightHorizontal、NarrowVertical、NarrowHorizontal、DarkVertical、DarkHorizontal、DashedDownwardDiagonal、DashedUpwardDiagonal、DashedHorizontal、DashedVertical——覆盖粗细、间距、虚线等线条形态变化。
装饰纹理类
SmallConfetti、LargeConfetti(大小彩纸点)、ZigZag(锯齿形)、Wave(波浪形)、DiagonalBrick、HorizontalBrick(砖墙形)、Weave(编织形)、Plaid(格子呢)、Divot(草皮形)、DottedGrid(点状网格)、DottedDiamond(点状菱形)、Shingle(瓦片形)、Trellis(栅格)、Sphere(球形)、SmallGrid、SmallCheckerBoard、LargeCheckerBoard(棋盘格)、OutlinedDiamond、SolidDiamond(菱形轮廓/实心)。
得益于枚举的顺序定义,你可以在代码中通过Enum.GetValues或EnumDataProvider枚举全部图案,结合 UI 下拉框实时预览(见第五节)。
四、实现原理:从 8×8 位图到平铺 DrawingBrush
理解生成器的底层实现,有助于预判它在不同渲染场景下的行为。源码 HatchBrushGenerator.cs 的核心逻辑可分为三部分。
1. 内置 8×8 位图图案表
类内部维护了一个静态二维字节数组HatchBrushes,每种样式对应 8 个字节,每个字节代表一行,共 8 行,即一张 8×8 的像素位图;字节中每一位为 1 的位置即前景点。例如:
new byte[] {0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00}, // Horizontal new byte[] {0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}, // Vertical new byte[] {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}, // ForwardDiagonal new byte[] {0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81}, // DiagonalCrossHorizontal的第 4 行为0xff(全 1),其余行全 0,因此渲染结果是一条贯穿的横线——这正是 WinForms 同名样式的视觉语义,也是文档所称"行为与 WinForms 一致"的根源。
2. 位图到几何图形的转换
GetHatchBrush首先通过GetHatchData取出对应样式的 8 个字节,然后双重循环遍历 8×8 网格,用位运算(hatchData[y] & (0x80 >> x)) > 0判断每个像素点是否为前景点,是则向GeometryGroup追加一个 1×1 的RectangleGeometry:
for (var y = 0; y < 8; y++) { for (var x = 0; x < 8; x++) { if ((hatchData[y] & (0x80 >> x)) > 0) { foreGeometryGroup.Children.Add(new RectangleGeometry(new Rect(x, y, 1, 1))); } } }3. 组装平铺画刷并开启缓存
画刷由两层GeometryDrawing组成:底层是用backColor填充的 8×8 背景矩形,上层是用foreColor填充的前景几何组。关键配置:
Viewport = new Rect(0, 0, 8, 8), // 平铺单元尺寸 ViewportUnits = BrushMappingMode.Absolute, // 以设备无关像素(DIP)为单元 Stretch = Stretch.None, // 不拉伸单元 TileMode = TileMode.Tile, // 沿两个方向平铺最后一行RenderOptions.SetCachingHint(drawingBrush, CachingHint.Cache);为画刷开启渲染缓存,图案会被缓存为位图以便重复绘制,在长列表、大数据面板等高频重绘场景下可显著减少几何重建开销。注意ViewportUnits = Absolute意味着平铺单元固定为 8 DIP,与控件缩放无关,图案密度不会随元素尺寸变化而改变——这是使用中需要留意的行为特征。
另外,GetHatchData对越界枚举做了防御:若传入值超出Horizontal到SolidDiamond的范围,会抛出ArgumentOutOfRangeException,因此传入非法枚举值是不安全的。
五、在 XAML / MVVM 中的集成方式
虽然文档只展示了代码调用方式,仓库的示例工程(HatchBrushGeneratorDemo.xaml)提供了一套完整的数据驱动集成范式,适合在真实项目中复用。
1. 用 EnumDataProvider 提供 HatchStyle 数据源
示例工程在 App.xaml 中通过hc:EnumDataProvider将HatchStyle枚举暴露为静态资源:
<hc:EnumDataProvider x:Key="HatchStyles" Type="hc:HatchStyle"/>EnumDataProvider(源码见 EnumDataProvider.cs)继承自ObjectDataProvider,构造时自动将方法名设为GetValues,Type赋值时通过反射调用Enum.GetValues枚举全部成员,并可结合BrowsableAttribute/DescriptionAttribute过滤与本地化显示。
2. 用 IValueConverter 把枚举转成画刷
示例定义了 HatchBrushConverter.cs,实现IValueConverter,将HatchStyle值转换为DrawingBrush:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is HatchStyle style) { return _brushGenerator.GetHatchBrush(style, ResourceHelper.GetResource<Color>(ResourceToken.DarkPrimaryColor), Colors.Transparent); } return Brushes.Transparent; }这里前景色取自主题资源DarkPrimaryColor,背景色使用Colors.Transparent,从而让阴影图案叠加在控件的底层背景之上。ConvertBack抛出NotSupportedException,表明这是单向转换。
3. 绑定到 UI
<Border Style="{StaticResource BorderRegion}" Margin="32" Background="{Binding SelectedValue, ElementName=ComboBoxDemo, Converter={StaticResource HatchBrushConverter}}"> <ComboBox SelectedIndex="0" VerticalAlignment="Center" Name="ComboBoxDemo" Width="180" ItemsSource="{Binding Source={StaticResource HatchStyles}}"/> </Border>当用户在ComboBox中选择不同的HatchStyle时,转换器即生成对应图案画刷,Border的背景实时更新,形成一个开箱即用的 53 种图案预览器。这套"枚举数据源 + 值转换器 + 绑定"的组合可直接迁移到属性面板、主题设计器等需要动态切换图案的场景。
六、使用建议与注意事项
- 颜色的选取:前景色决定图案可见度,建议与背景色保持足够对比度;如需让图案叠在已有 UI 之上,可仿照示例将背景色设为
Colors.Transparent。 - 平铺尺寸固定:由于
ViewportUnits为Absolute且单元为 8×8,图案密度不随元素大小缩放;若需要放大/缩小纹理,可自行在外部对画刷做变换(如ScaleTransform),或在理解该行为的前提下接受固定密度。 - 复用生成器实例:
HatchBrushGenerator是无状态工具类,可像示例中的HatchBrushConverter一样作为单例/成员字段长期复用,避免每次调用都重复创建。 - 缓存已开启:生成器内部已设置
CachingHint.Cache,同一画刷用于大量元素时具有较好渲染性能,无需再手动缓存。 - 枚举合法性:
GetHatchData对越界值抛出ArgumentOutOfRangeException,业务代码中应避免传入无效枚举。
HatchBrushGenerator 将 WinForms 时代成熟的阴影纹理体系带入了 WPF 与 HandyControl 生态,无论是构建数据可视化底纹、模拟纸张/工程图纸背景,还是为自定义控件提供装饰填充,它都是轻量而可靠的选择。进一步可阅读 tools 目录 下的其他工具文档,结合Effect、MorphingAnimation等能力搭建更丰富的视觉效果。
- UI组件
- 桌面应用
【免费下载链接】HandyControl
Contains some simple and commonly used WPF controls
相关推荐
Flet BlurStyle 完全指南:掌握四种阴影模糊渲染风格
Flet BlurStyle 完全指南:掌握四种阴影模糊渲染风格 导读 flet.BlurStyle 是 Flet 框架中控制 阴影(BoxShadow)模糊渲
前端跨平台桌面应用移动开发ExcalidrawZ 使用指南:macOS 手绘风格绘图工具
ExcalidrawZ 使用指南:macOS 手绘风格绘图工具 ExcalidrawZ 是一款基于 SwiftUI 构建的 macOS 绘图应用,它扩展了 Ex
跨平台图像处理终极指南:使用ImageSharp在WinForms/WPF/UWP中快速集成
跨平台图像处理终极指南:使用ImageSharp在WinForms/WPF/UWP中快速集成 ImageSharp 是一个功能强大的跨平台2D图形处理库,专门为
图像处理图形学
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考