【笔记】WPF中 Brush 的类型、继承关系、使用方式和注意事项

1. Brush 的作用

WPF 中 Brush 用来"绘制区域",常见于:

xml 复制代码
<Border Background="LightBlue" />
<TextBlock Foreground="Red" />
<Rectangle Fill="Orange" Stroke="Black" />
<Path Fill="Blue" Stroke="DarkBlue" />

常用属性包括:

控件 / 图形 常见 Brush 属性
Control Background、Foreground、BorderBrush
TextBlock Foreground
Border Background、BorderBrush
Shape Fill、Stroke
Panel Background

2. Brush 继承关系

WPF 中 Brush 的主要继承结构如下:

plaintext 复制代码
System.Object
 └─ DispatcherObject
    └─ DependencyObject
       └─ Freezable
          └─ Animatable
             └─ Brush
                ├─ SolidColorBrush
                ├─ GradientBrush
                │  ├─ LinearGradientBrush
                │  └─ RadialGradientBrush
                └─ TileBrush
                   ├─ ImageBrush
                   ├─ DrawingBrush
                   ├─ VisualBrush
                   └─ BitmapCacheBrush

关键点

基类 说明
DispatcherObject 和 UI 线程关联
DependencyObject 支持依赖属性
Freezable 支持冻结,提高性能
Animatable 支持动画
Brush 所有画刷的抽象基类

3. 常见 Brush 类型

3.1 SolidColorBrush

单色画刷,最常用。

XAML

xml 复制代码
<Border Background="LightBlue"
        BorderBrush="DarkBlue"
        BorderThickness="1" />

等价写法:

xml 复制代码
<Border>
    <Border.Background>
        <SolidColorBrush Color="LightBlue" />
    </Border.Background>
</Border>

C#

csharp 复制代码
var border = new Border();
border.Background = new SolidColorBrush(Colors.LightBlue);
border.BorderBrush = Brushes.DarkBlue;

适用场景

  • 普通背景色
  • 文本颜色
  • 边框颜色
  • 图形填充
  • 图形描边

3.2 Brushes

Brushes 不是 Brush 子类,而是一个静态工具类,提供预定义 SolidColorBrush。

csharp 复制代码
textBlock.Foreground = Brushes.Red;
border.Background = Brushes.Transparent;
rectangle.Fill = Brushes.LightGray;

常见值:

csharp 复制代码
Brushes.Black
Brushes.White
Brushes.Red
Brushes.Blue
Brushes.Transparent
Brushes.LightGray
Brushes.DarkGray

3.3 LinearGradientBrush

线性渐变画刷,颜色沿一条直线过渡。

XAML

xml 复制代码
<Border Width="200" Height="100">
    <Border.Background>
        <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
            <GradientStop Color="Red" Offset="0" />
            <GradientStop Color="Yellow" Offset="0.5" />
            <GradientStop Color="Blue" Offset="1" />
        </LinearGradientBrush>
    </Border.Background>
</Border>

常见方向

xml 复制代码
<!-- 从左到右 -->
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0" />

<!-- 从上到下 -->
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1" />

<!-- 左上到右下 -->
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1" />

C#

csharp 复制代码
var brush = new LinearGradientBrush();
brush.StartPoint = new Point(0, 0);
brush.EndPoint = new Point(1, 1);
brush.GradientStops.Add(new GradientStop(Colors.Red, 0));
brush.GradientStops.Add(new GradientStop(Colors.Blue, 1));

border.Background = brush;

3.4 RadialGradientBrush

径向渐变画刷,从中心向外扩散。

XAML

xml 复制代码
<Ellipse Width="150" Height="150">
    <Ellipse.Fill>
        <RadialGradientBrush Center="0.5,0.5"
                             GradientOrigin="0.3,0.3"
                             RadiusX="0.8"
                             RadiusY="0.8">
            <GradientStop Color="White" Offset="0" />
            <GradientStop Color="SkyBlue" Offset="0.5" />
            <GradientStop Color="DarkBlue" Offset="1" />
        </RadialGradientBrush>
    </Ellipse.Fill>
</Ellipse>

常用属性

属性 说明
Center 渐变圆心
GradientOrigin 渐变起始点
RadiusX X 方向半径
RadiusY Y 方向半径
GradientStops 渐变颜色节点集合

3.5 ImageBrush

使用图片作为填充。

XAML

xml 复制代码
<Rectangle Width="300" Height="150">
    <Rectangle.Fill>
        <ImageBrush ImageSource="/Images/bg.png"
                    Stretch="UniformToFill" />
    </Rectangle.Fill>
</Rectangle>

常用 Stretch

值 说明
None 不缩放
Fill 填满,可能变形
Uniform 等比例完整显示,可能留白
UniformToFill 等比例填满,可能裁剪

图片平铺

xml 复制代码
<Rectangle Width="300" Height="200">
    <Rectangle.Fill>
        <ImageBrush ImageSource="/Images/tile.png"
                    TileMode="Tile"
                    Viewport="0,0,50,50"
                    ViewportUnits="Absolute" />
    </Rectangle.Fill>
</Rectangle>

3.6 VisualBrush

使用某个 WPF Visual 元素作为画刷。

示例

xml 复制代码
<StackPanel>
    <TextBlock x:Name="SourceText"
               Text="VisualBrush"
               FontSize="32"
               Foreground="Red" />

    <Rectangle Width="300" Height="100">
        <Rectangle.Fill>
            <VisualBrush Visual="{Binding ElementName=SourceText}" />
        </Rectangle.Fill>
    </Rectangle>
</StackPanel>

适用场景

  • 镜像效果
  • 水印
  • 控件预览
  • 将复杂 UI 当作背景

注意

VisualBrush 性能成本较高,不适合大量频繁使用。


3.7 DrawingBrush

使用矢量 Drawing 作为画刷,适合轻量图案。

网格 / 纹理示例

xml 复制代码
<Rectangle Width="300" Height="200">
    <Rectangle.Fill>
        <DrawingBrush TileMode="Tile"
                      Viewport="0,0,20,20"
                      ViewportUnits="Absolute">
            <DrawingBrush.Drawing>
                <GeometryDrawing Brush="LightGray">
                    <GeometryDrawing.Geometry>
                        <RectangleGeometry Rect="0,0,10,10" />
                    </GeometryDrawing.Geometry>
                </GeometryDrawing>
            </DrawingBrush.Drawing>
        </DrawingBrush>
    </Rectangle.Fill>
</Rectangle>

适用场景

  • 网格背景
  • 斜线填充
  • 简单矢量纹理
  • 可重复图案

3.8 BitmapCacheBrush

BitmapCacheBrush 使用缓存后的视觉内容作为画刷,较少直接使用。

适合对某些复杂视觉内容做缓存后复用,但普通场景一般优先考虑:

  • 简单颜色:SolidColorBrush
  • 图片:ImageBrush
  • 矢量图案:DrawingBrush
  • UI 元素:VisualBrush

4. Brush 常用公共属性

所有 Brush 都有这些常用属性:

属性 说明
Opacity 画刷透明度
Transform 绝对变换
RelativeTransform 相对变换

Brush.Opacity

xml 复制代码
<Border>
    <Border.Background>
        <SolidColorBrush Color="Red" Opacity="0.5" />
    </Border.Background>
</Border>

注意:这是只让背景半透明。

如果写在控件上:

xml 复制代码
<Border Background="Red" Opacity="0.5">
    <TextBlock Text="Text" />
</Border>

整个 Border 包括子元素都会半透明。


5. 资源中定义 Brush

推荐把常用画刷放到资源里。

xml 复制代码
<Window.Resources>
    <SolidColorBrush x:Key="PrimaryBrush" Color="#0078D4" />
    <SolidColorBrush x:Key="DangerBrush" Color="#D13438" />
</Window.Resources>

<Button Background="{StaticResource PrimaryBrush}"
        Foreground="White"
        Content="Save" />

如果需要主题动态切换,可以使用:

xml 复制代码
<Button Background="{DynamicResource PrimaryBrush}" />

StaticResource 和 DynamicResource

类型 说明
StaticResource 加载时解析,性能较好
DynamicResource 运行时查找,适合主题切换

6. 使用 Brush 的注意事项

6.1 不要修改 Brushes.xxx

不推荐:

csharp 复制代码
Brushes.Red.Opacity = 0.5;

推荐:

csharp 复制代码
var brush = new SolidColorBrush(Colors.Red)
{
    Opacity = 0.5
};

原因:Brushes.Red 是共享对象,修改后可能影响其他地方。


6.2 资源 Brush 可能被多个控件共享

xml 复制代码
<Window.Resources>
    <SolidColorBrush x:Key="PrimaryBrush" Color="Blue" />
</Window.Resources>

<Button Background="{StaticResource PrimaryBrush}" />
<TextBlock Foreground="{StaticResource PrimaryBrush}" />

如果在代码中修改 PrimaryBrush,所有引用它的控件都会受影响。

如果只想修改单个控件,应克隆:

csharp 复制代码
var brush = button.Background as SolidColorBrush;
button.Background = brush?.Clone();

6.3 Frozen Brush 不能修改

Brush 继承自 Freezable,可能被冻结。

csharp 复制代码
if (brush.IsFrozen)
{
    brush = brush.Clone();
}

冻结后不能修改,但性能更好。

csharp 复制代码
var brush = new SolidColorBrush(Colors.Red);
brush.Freeze();

6.4 Brush 通常和 UI 线程绑定

Brush 继承自 DispatcherObject,通常只能在创建它的 UI 线程访问。

如果需要跨线程读取,可以冻结:

csharp 复制代码
var brush = new SolidColorBrush(Colors.Red);
brush.Freeze();

6.5 Transparent 和 null 不一样

xml 复制代码
<Grid Background="Transparent" />

表示背景透明,但可以接收鼠标事件。

xml 复制代码
<Grid Background="{x:Null}" />

表示没有背景,空白区域可能无法命中鼠标事件。

如果需要点击空白区域,应使用:

xml 复制代码
<Grid Background="Transparent" />

6.6 Color 和 Brush 不是同一种类型

错误:

csharp 复制代码
border.Background = Colors.Red;

正确:

csharp 复制代码
border.Background = Brushes.Red;

或:

csharp 复制代码
border.Background = new SolidColorBrush(Colors.Red);

6.7 动画时不要共享 Brush

如果多个控件共享同一个 Brush,动画修改颜色时可能影响多个控件。

更安全:

xml 复制代码
<Button Content="Hover">
    <Button.Background>
        <SolidColorBrush Color="LightBlue" />
    </Button.Background>
</Button>

不要多个控件共享同一个正在动画的 SolidColorBrush。


6.8 ImageBrush 注意图片路径

常见路径:

xml 复制代码
<ImageBrush ImageSource="/Images/bg.png" />

跨程序集:

xml 复制代码
<ImageBrush ImageSource="/YourAssemblyName;component/Images/bg.png" />

图片文件常见配置:

Build Action 说明
Resource 嵌入程序集
Content 复制到输出目录

7. 如何选择 Brush

需求 推荐
普通纯色 SolidColorBrush / Brushes
线性渐变 LinearGradientBrush
圆形光晕 / 径向高光 RadialGradientBrush
图片背景 ImageBrush
控件作为背景 VisualBrush
网格 / 斜线 / 纹理 DrawingBrush
需要复用固定颜色 资源中的 SolidColorBrush
需要主题切换 DynamicResource
需要动画 控件独立 Brush
需要高性能复用 冻结 Brush

8. 总结

最常用的是:

plaintext 复制代码
Brush
 ├─ SolidColorBrush        // 单色,最常用
 ├─ LinearGradientBrush    // 线性渐变
 ├─ RadialGradientBrush    // 径向渐变
 ├─ ImageBrush             // 图片填充
 ├─ DrawingBrush           // 矢量纹理
 └─ VisualBrush            // UI 元素填充

实际开发中优先级通常是:

  1. 简单颜色用 Brushes.xxx 或 SolidColorBrush
  2. 可复用颜色放到资源中
  3. 主题切换用 DynamicResource
  4. 图片填充用 ImageBrush
  5. 简单纹理用 DrawingBrush
  6. 复杂 UI 填充才考虑 VisualBrush
  7. 要修改或动画时,避免直接修改共享 Brush
相关推荐
DP DPharness3 小时前
ClearAI、记忆插件与普通笔记,三种让 Agent 记住的路数对比
笔记
piikee6 小时前
粤语初学入门:从粤拼、九声六调到开口,一个普通话母语者的练习笔记
笔记·粤语入门·怎么学习粤语
Seraphina368 小时前
SQL注入(二)盲注
网络·数据库·经验分享·笔记·sql
白山编程大哥8 小时前
Carsim 2024.1 专业安装介绍:功能特性与应用场景详解
笔记
hss123456788 小时前
整装落地与效果图差距有多大?从毫米级误差到ENF板材的量化拆解
笔记
zhangrelay11 小时前
用ROS2Lyrical实验报告册思路重做蓝桥云课ROS1实验并改进
linux·笔记·学习·ubuntu·机器人
LHR_friendship12 小时前
HCIP课程全部内容
网络·笔记·学习·hcip·华为ensp
海绵宝宝转agent13 小时前
Pico 学习笔记 Harness 设计、历史压缩、三类目录与缓存复用
笔记·学习·缓存
xUxIAOrUIII15 小时前
日常笔记-1005-1
linux·笔记·python·macos