Win8ProgressRing 控件






4.97/5 (30投票s)
本文介绍了一个名为 Win8ProgressRing 的用户自定义控件,该控件模仿了 Windows 8 的进度圆环。
- 下载 Win8ProgressRing 控件源代码 - 6.9 KB
- 下载 Win8ProgressRing 演示源代码 - 16.2 KB
- 下载 Win8ProgressRing 演示可执行文件 - 17.3 KB
引言    
 
本文简要介绍了一个名为 Win8ProgressRing 的控件,该控件模仿了 Windows 8 的进度圆环。
这里只会简要讨论其实现。在接下来的讨论中,由开发者指定的属性将以 粗体混合大小写 显示。软件内部使用的变量将以 斜体小写 显示。
视觉属性    
 

Win8ProgressRing 控件有两个属性用于构成用户的视觉图像。在右侧的图中,控件的边界以 红色 绘制。
开发者通过将控件从工具箱拖放到窗体上的位置来指定控件的左上角。该位置成为控件图形环境中的 ( 0, 0 )。开发者通过拖动控件的调整大小柄或指定 Control_Height 属性来指定 control_height。 control_width 被设置为等于 control_height。
指示器的颜色默认为白色。要更改指示器的颜色,开发者可以通过 Indicator_Color 属性指定新颜色。
控件的背景是透明的,无法更改。
控件属性    
 
Win8ProgressRing 控件具有以下可供开发者使用的属性:
| 名称 | 描述 | |
| 动画 | 获取或设置一个值,该值指示控件是否自动旋转指示器。如果为 true,则控件会为指示器旋转创建动画;如果为 false,则控件仅在调用 Pulse 方法时移动指示器。默认值为 true。 | |
| Control_Height | 获取或设置控件的高度。更改此属性时,也会更改控件的其他内部值。默认值为 100 像素。 // ********************* adjust_control_dimensions_from_height
void adjust_control_dimensions_from_height ( int new_height )
    {
    indicator_radius = round ( ( double ) new_height / 
                               ( double ) SIZE_FACTOR );
    indicator_diameter = 2 * indicator_radius;
    control_height = SIZE_FACTOR * indicator_radius;
    control_width = control_height;
    outer_radius = control_height / 2;
    inner_radius = outer_radius - indicator_diameter;
    indicator_center_radius = inner_radius + 
                              indicator_radius;
    this.Height = control_height;
    this.Width = control_width;
    }
 | |
| Indicator_Color | 获取或设置 Win8ProgressRing 控件中指示器的颜色。默认值为 Color.White。 | |
| Refresh_Rate | 指示器移动之间的时间(以毫秒为单位)。该值必须大于或等于 10,且小于或等于 200。默认值为 100 毫秒。 | 
Pulse 方法用于在每次调用时旋转指示器一次。其签名如下:
  public void Pulse ( )
  
实现    
 

Win8ProgressRing 控件是一个 用户自定义控件。控件的某些部分在控件的 OnPaint 方法被调用时绘制。
控件的图形由两个不同的图形图像组成:背景图形和指示器图形。
背景图形一旦绘制,除非 Control_Height 被更改,否则无需重新绘制。当背景图形重新绘制时;当动画改变指示器位置时;或当指示器颜色更改时,指示器图形必须重新绘制。
控件由六个圆形指示器组成,这些指示器围绕控件中心旋转。最初,指示器聚集在一起,从 90 度开始。
注意
控件使用 Windows 坐标系,x 轴值向右增加;y 轴值向下增加;角度从 x 轴开始顺时针测量。
从最顺时针的指示器开始,它顺时针移动 11.25 度。如果指示器进入控件的快速移动区域,在下一次迭代中,它将移动 11.25 度的某个倍数。
角度增量 (11.25) 源于希望在每个象限显示八个指示器。这导致控件周围有 32 个指示器。360 除以 32 得到 11.25 度的增量。
由于在每次指示器前进时都会调用正弦和余弦三角函数,因此在初始化时会生成两个表,其中包含 1440 个以 0.25 度为增量的三角函数值。
六个指示器中的每一个都是 Indicator 类的实例。
    // *********************************************** class Indicator
    public class Indicator
        {
        double  degrees = 0.0;
        double  fast = 1.0;
        // ************************************************* Indicator
        public Indicator ( )
            {
            Degrees = 0.0;
            Fast = 1.0;
            }
        // ************************************************* Indicator
        public Indicator ( double  degrees )
            {
            Degrees = degrees;
            Fast = 1.0;
            }
        // *************************************************** Degrees
        public double Degrees
            {
            get
                {
                return ( degrees );
                }
            set
                {
                degrees = value;
                }
            }
        // ****************************************************** Fast
        public double Fast
            {
            get
                {
                return ( fast );
                }
            set
                {
                fast = value;
                }
            }
        } // class Indicator
  
最后,每次间隔计时器触发 elapsed 事件时,都会调用 draw_indicator_graphic。
    // ************************************ draw_indicator_graphic
    void draw_indicator_graphic (  Graphics graphics )
        {
        Brush       brush = new SolidBrush ( Indicator_Color );
        Rectangle   rectangle = new Rectangle ( );
        for ( int i = ( MAXIMUM_INDICATORS - 1 ); 
                  ( i >= 0 ); 
                  i-- )
            {
            double  degrees = indicators [ i ].Degrees;
            int     dx;
            int     dy;
            if ( degrees < 0.0 )
                {
                degrees += 360.0;
                }
            dx = round ( ( double ) indicator_center_radius *
                         cos ( degrees ) ) +
                 indicator_center_radius;
            dy = indicator_center_radius -
                 round ( ( double ) indicator_center_radius *
                         sin ( degrees ) );
            rectangle.Location = new Point ( dx, dy );
            rectangle.Size = new Size ( indicator_diameter,
                                        indicator_diameter );
            graphics.FillEllipse ( brush, rectangle );
            degrees -= ( double ) indicators [ i ].Fast * 
                       INDICATOR_OFFSET;
            if ( indicators [ i ].Fast > 1.0 )
                {
                indicators [ i ].Fast += 0.25;
                }
            if ( degrees < 0.0 )
                {
                indicators [ i ].Fast = 1.25;
                }
            else if ( degrees < START_AT )
                {
                indicators [ i ].Fast = 1.0;
                }
            indicators [ i ].Degrees = degrees;
            }
        brush.Dispose ( );
        }
  
图形缓冲区    
 
GraphicsBuffer 类包含一个屏幕外位图,用于在不闪烁的情况下绘制图形对象。虽然 .Net 提供了 双缓冲图形 功能,但对于 Win8ProgressRing 控件来说,这有点大材小用了。
GraphicsBuffer 已包含在控件中。
结论    
 
本文介绍了一个模仿 Windows 8 进度圆环的控件。
参考文献    
 
开发环境    
 
Win8ProgressRing 控件在以下环境中开发:
| Microsoft Windows 7 Professional Service Pack 1 | |
| Microsoft Visual Studio 2008 Professional | |
| Microsoft .Net Framework Version 3.5 SP1 | |
| Microsoft Visual C# 2008 | 
历史    
 
| 09/03/2013 | 原始文章 | |
| 03/27/2015 | 添加了演示可执行文件下载;进行了少量编辑;使用 Auto-TOC Generator 重新生成了目录。 | 



