【笔记】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 BackgroundForegroundBorderBrush
TextBlock Foreground
Border BackgroundBorderBrush
Shape FillStroke
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}" />

StaticResourceDynamicResource

类型 说明
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 Transparentnull 不一样

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

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

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

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

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

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

6.6 ColorBrush 不是同一种类型

错误:

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.xxxSolidColorBrush
  2. 可复用颜色放到资源中
  3. 主题切换用 DynamicResource
  4. 图片填充用 ImageBrush
  5. 简单纹理用 DrawingBrush
  6. 复杂 UI 填充才考虑 VisualBrush
  7. 要修改或动画时,避免直接修改共享 Brush
相关推荐
阿米亚波1 小时前
【C++ STL】std::forward_list
开发语言·c++·笔记·stl·visual studio·forward_list
Z5998178412 小时前
c#软件开发学习笔记--事务、索引
笔记·学习·c#
宵时待雨2 小时前
linux笔记归纳9:进程间通信
linux·服务器·笔记
疯狂打码的少年2 小时前
【软件工程】结构化设计:结构化设计方法(SC图)
笔记·软件工程
十月的皮皮2 小时前
C语言学习笔记20260716-编译与链接
c语言·笔记·学习
影视飓风TIM3 小时前
Linux基础入门笔记:命令、内核架构与压缩传输全梳理
linux·笔记·架构
chouchuang15 小时前
day-030-综合练习-笔记管理器
开发语言·笔记·python
岑梓铭20 小时前
《考研408数据结构》第六章(6.3 图的遍历)复习笔记
数据结构·笔记·考研··拓扑排序·408
he_wen_jian20 小时前
【无标题】
笔记