65.9K
CodeProject 正在变化。 阅读更多。
Home

类似于 SQL Server 2005 中的进度圆盘

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.71/5 (43投票s)

2006年7月16日

CPOL

2分钟阅读

viewsIcon

118804

downloadIcon

2585

使用 GDI+ 的内置方法绘制类似于 SQL Server 2005 中进度圆盘。

Sample screenshot

引言

进度盘是一个简单的控件,我在看到 SQL Server 2005 中的那个之后编写的。它可以用来替换旧的进度条,呈现出一种美观且色彩丰富的渐变色组合。

想法

.NET 2.0 类库拥有 Graphics 对象,它负责绘制 2D 图形。它包含点、线、矩形、椭圆、扇形等基本形状。我使用 DrawPie 方法来绘制我的控件,该控件是通过在彼此之上绘制 3 层扇形形成的。

  • 底层第一层:一个起始角度为零、扫描角度为 360 度的扇形,用于绘制一个完整的圆,作为控件的背景。
  • 中间第二层:一个代表盘块的扇形;绘制了 12 个盘块(扇形片段),每个扇形片段的扫描角度为 25 度,分离角度为 5 度。
  • 顶层第三层:类似于第一层,但其功能是控制盘块的大小;绘制的圆越小,盘块看起来就越大(例如,绘制一个半径为零的内圆会产生像披萨切片形状的盘块)。

颜色

我使用线性渐变画笔填充盘块:2 种颜色用于非活动盘块,2 种颜色用于活动盘块。为了使控件更灵活,添加了以下属性:

  • Value:进度盘的当前值
  • BackGroundColor:背景颜色
  • ActiveForeColor1 & ActiveForeColor2:这两个颜色用于当前值的盘块
  • InactiveForeColor1 & InactiveForeColor2:这两个颜色用于其余盘块
  • SquareSize:包含控件的方形的边长
  • BlockSize:用于 6 种不同大小的枚举
  • SliceNumber:控件中的切片数量(由 Coyotelapa 添加)

代码

使用了 4 个 GraphicsPath 对象来绘制控件,每个层一个,以及额外的对象来为当前值的盘块着色。

    protected override void OnPaint(PaintEventArgs e)
        {
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
            region = new Region(ClientRectangle);
            if (backGrndColor == Color.Transparent)
            {
                region.Exclude(bkGroundPath2);
                Region = region;
            }

            e.Graphics.FillPath(new SolidBrush(backGrndColor), bkGroundPath1);
            e.Graphics.FillPath(
            new LinearGradientBrush(new Rectangle(0, 0, size, size), 
                inactiveforeColor1, inactiveforeColor2,
            value * 360 / 12, true), valuePath);
            e.Graphics.FillPath(
            new LinearGradientBrush(new Rectangle(0, 0, size, size), 
                activeforeColor1, activeforeColor2,
            value * 360 / 12, true), freGroundPath);
            e.Graphics.FillPath(new SolidBrush(backGrndColor), bkGroundPath2);

            base.OnPaint(e);
        }

    //The Render method called on any change to control(size,colors,..)

    private void Render()
        {
            
            bkGroundPath1.Reset();
            bkGroundPath2.Reset();
            valuePath.Reset();
            freGroundPath.Reset();
            bkGroundPath1.AddPie(new Rectangle(0, 0, size, size), 0, 360);

            //just in case...

            if (sliceCount == 0)
            {
                sliceCount = 12;
            }

            float sliceAngle = 360 / sliceCount;
            float sweepAngle = sliceAngle - 5;
            for (int i = 0; i < sliceCount; i++)
            {
                if (value != i)
                {
                    valuePath.AddPie(0, 0, size, size, i * sliceAngle, 
                        sweepAngle);
                }
            }
            bkGroundPath2.AddPie(
            (size / 2 - size * blockRatio), (size / 2 - size * blockRatio),
            (blockRatio * 2 * size), (blockRatio * 2 * size), 0, 360);
            freGroundPath.AddPie(new Rectangle(0, 0, size, size), 
                value * sliceAngle, sweepAngle);
            Invalidate();
        }

历史

  • 2006 年 7 月 16 日 - 发布原始版本
  • 2006 年 7 月 29 日 - 在添加 Coyotelapa 改进并修复一些错误后更新
  • 2007 年 5 月 31 日 - 编辑文章并移动到 CodeProject.com 的主要文章数据库
© . All rights reserved.