☰
HandyControl HatchBrushGenerator 使用指南:在 WPF 中绘制 50+ 种 WinForms 风格阴影图案
2026/10/3 2:18:07 网站建设 项目流程
  • UI组件
  • 桌面应用

【免费下载链接】HandyControl

Contains some simple and commonly used WPF controls

项目地址:https://gitcode.com/gh_mirrors/ha/HandyControl
点击查看免费下载

本文档(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, 前景色, 背景色);

其中三个参数的完整含义如下:

参数类型说明
hatchStyleHandyControl.Data.HatchStyle阴影图案样式,共 53 个枚举值(详见第三节)
foreColorSystem.Windows.Media.Color前景色,决定图案线条/点阵本身的颜色
backColorSystem.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}, // DiagonalCross

Horizontal的第 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 种图案预览器。这套"枚举数据源 + 值转换器 + 绑定"的组合可直接迁移到属性面板、主题设计器等需要动态切换图案的场景。

六、使用建议与注意事项

  1. 颜色的选取:前景色决定图案可见度,建议与背景色保持足够对比度;如需让图案叠在已有 UI 之上,可仿照示例将背景色设为Colors.Transparent。
  2. 平铺尺寸固定:由于ViewportUnits为Absolute且单元为 8×8,图案密度不随元素大小缩放;若需要放大/缩小纹理,可自行在外部对画刷做变换(如ScaleTransform),或在理解该行为的前提下接受固定密度。
  3. 复用生成器实例:HatchBrushGenerator是无状态工具类,可像示例中的HatchBrushConverter一样作为单例/成员字段长期复用,避免每次调用都重复创建。
  4. 缓存已开启:生成器内部已设置CachingHint.Cache,同一画刷用于大量元素时具有较好渲染性能,无需再手动缓存。
  5. 枚举合法性:GetHatchData对越界值抛出ArgumentOutOfRangeException,业务代码中应避免传入无效枚举。

HatchBrushGenerator 将 WinForms 时代成熟的阴影纹理体系带入了 WPF 与 HandyControl 生态,无论是构建数据可视化底纹、模拟纸张/工程图纸背景,还是为自定义控件提供装饰填充,它都是轻量而可靠的选择。进一步可阅读 tools 目录 下的其他工具文档,结合Effect、MorphingAnimation等能力搭建更丰富的视觉效果。

  • UI组件
  • 桌面应用

【免费下载链接】HandyControl

Contains some simple and commonly used WPF controls

项目地址:https://gitcode.com/gh_mirrors/ha/HandyControl
点击查看免费下载
上一篇:Wand-Enhancer技术架构深度解析与本地化增强方案实践指南
下一篇:WeMod增强器终极指南:3步解锁专业版完整功能 🚀

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询