当前位置: 代码网 > it编程>编程语言>Asp.net > C#中的Drawing 类案例详解

C#中的Drawing 类案例详解

2025年08月08日 Asp.net 我要评论
一、drawing 是什么?命名空间wpf:system.windows.mediawinforms:system.drawing(gdi+)继承链(wpf)object → dispatc

一、drawing 是什么?

命名空间

  • wpf:system.windows.media
  • winforms:system.drawing(gdi+)

继承链(wpf)

  • object → dispatcherobject → dependencyobject → freezable → animatable → drawing

常用派生类:

  • geometrydrawing(用 path 画形状)
  • imagedrawing(贴位图)
  • videodrawing(播放视频)
  • glyphrundrawing(文字)
  •  drawinggroup(容器,可组合其它 drawing)

特点

  • 轻量级:只存“矢量指令”,不继承 uielement,不参与布局/事件路由。
  • 可冻结(freeze):变为只读后可跨线程使用。
  • 可序列化/导出为 xaml。

二、典型用法

  • 直接放在控件里
  • 用 drawingbrush 或 drawingimage 把 drawing 变成 brush/image,再赋给控件的 background、source 等属性。
  • 在 drawingvisual 里绘制
  • 适合自定义控件、命中测试、打印。
  • 在 drawinggroup 里组合
  • 把多个 drawing 套娃,实现复杂场景。

三、案例:画一个“带阴影的圆角矩形按钮”

目标:

  • 圆角矩形(填充线性渐变、描边)
  • 下方有一层模糊阴影(半透明黑圆角矩形)
  •  鼠标悬停时整体高亮(动画改变渐变)

wpf:

<window x:class="demodrawing.mainwindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        title="drawing 示例" width="300" height="200">
    <grid>
        <!-- 使用 drawingbrush 做背景 -->
        <rectangle x:name="btnrect" width="180" height="60"
                   mouseenter="btnrect_mouseenter"
                   mouseleave="btnrect_mouseleave">
            <rectangle.resources>
                <!-- 阴影 drawing -->
                <geometrydrawing x:key="shadow"
                                 geometry="m 5,5 175,5 175,55 5,55 z"
                                 brush="#80000000">
                    <geometrydrawing.pen>
                        <pen brush="transparent" thickness="1"/>
                    </geometrydrawing.pen>
                </geometrydrawing>
                <!-- 按钮主体 drawing -->
                <geometrydrawing x:key="body" geometry="m 0,0 170,0 170,50 0,50 z">
                    <geometrydrawing.brush>
                        <lineargradientbrush startpoint="0,0" endpoint="0,1">
                            <gradientstop offset="0"  color="#ff4c9aff"/>
                            <gradientstop offset="1"  color="#ff0050dd"/>
                        </lineargradientbrush>
                    </geometrydrawing.brush>
                    <geometrydrawing.pen>
                        <pen brush="#ff003399" thickness="2"/>
                    </geometrydrawing.pen>
                </geometrydrawing>
                <!-- 组合 drawinggroup -->
                <drawinggroup x:key="combined">
                    <!-- 先画阴影 -->
                    <drawinggroup.children>
                        <drawinggroup>
                            <drawinggroup.children>
                                <staticresource resourcekey="shadow"/>
                            </drawinggroup.children>
                            <drawinggroup.bitmapeffect>
                                <blurbitmapeffect radius="5"/>
                            </drawinggroup.bitmapeffect>
                        </drawinggroup>
                        <!-- 再画按钮主体 -->
                        <staticresource resourcekey="body"/>
                    </drawinggroup.children>
                </drawinggroup>
                <!-- 把 drawinggroup 变成 brush -->
                <drawingbrush x:key="btnbrush" drawing="{staticresource combined}"/>
            </rectangle.resources>
            <rectangle.fill>
                <staticresource resourcekey="btnbrush"/>
            </rectangle.fill>
        </rectangle>
    </grid>
</window>

后台代码

public partial class mainwindow : window
{
    public mainwindow()
    {
        initializecomponent();
    }
    private void btnrect_mouseenter(object sender, mouseeventargs e)
    {
        // 找到 drawing 里的渐变刷
        var rect = (rectangle)sender;
        var brush = (drawingbrush)rect.fill;
        var dg = (drawinggroup)brush.drawing;
        var body = (geometrydrawing)((drawinggroup)dg.children[1]).children[0];
        var lg = (lineargradientbrush)body.brush;
        // 动画高亮
        var da = new coloranimation(color.fromrgb(0x6f, 0xba, 0xff),
                                    timespan.frommilliseconds(300));
        lg.gradientstops[0].beginanimation(gradientstop.colorproperty, da);
    }
    private void btnrect_mouseleave(object sender, mouseeventargs e)
    {
        var rect = (rectangle)sender;
        var brush = (drawingbrush)rect.fill;
        var dg = (drawinggroup)brush.drawing;
        var body = (geometrydrawing)((drawinggroup)dg.children[1]).children[0];
        var lg = (lineargradientbrush)body.brush;
        var da = new coloranimation(color.fromrgb(0x4c, 0x9a, 0xff),
                                    timespan.frommilliseconds(300));
        lg.gradientstops[0].beginanimation(gradientstop.colorproperty, da);
    }
}

四、winforms(gdi+)对应写法

winforms 没有 drawing 类,而是 graphicspath + lineargradientbrush + bitmap 的“即时模式”绘制。核心步骤:

protected override void onpaint(painteventargs e)
{
    var g = e.graphics;
    g.smoothingmode = smoothingmode.antialias;
    // 1. 阴影
    using (var path = createroundrect(5, 5, 175, 55, 8))
    using (var brush = new solidbrush(color.fromargb(128, 0, 0, 0)))
    using (var blur = new bitmap(180, 60))
    {
        using (var g2 = graphics.fromimage(blur))
        {
            g2.smoothingmode = smoothingmode.antialias;
            g2.fillpath(brush, path);
        }
        // 手动高斯模糊(略)...
        g.drawimage(blur, 0, 0);
    }
    // 2. 主体
    using (var path = createroundrect(0, 0, 170, 50, 8))
    using (var brush = new lineargradientbrush(
        new point(0, 0), new point(0, 50),
        color.fromargb(255, 0x4c, 0x9a, 0xff),
        color.fromargb(255, 0x00, 0x50, 0xdd)))
    using (var pen = new pen(color.fromargb(255, 0x00, 0x33, 0x99), 2))
    {
        g.fillpath(brush, path);
        g.drawpath(pen, path);
    }
}
private graphicspath createroundrect(float x, float y, float w, float h, float r)
{
    var gp = new graphicspath();
    gp.addarc(x + w - r, y, r, r, 270, 90);
    gp.addarc(x + w - r, y + h - r, r, r, 0, 90);
    gp.addarc(x, y + h - r, r, r, 90, 90);
    gp.addarc(x, y, r, r, 180, 90);
    gp.closefigure();
    return gp;
}
  •  wpf 的 drawing 体系是“矢量指令树”,轻量、可缓存、可动画,适合高性能场景(千级图形)。
  •  常用套路:geometrydrawing/drawinggroup → drawingbrush/drawingimage → shape 或 image 控件。
  •  winforms 没有 drawing 类,用 graphics 即时绘制;想缓存可用 bitmap/ metafile。

到此这篇关于c#drawing 类详解的文章就介绍到这了,更多相关c# drawing 类内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com