ProgressCircle -ProgressBar 的替代方案
这是一个自定义控件,是 Visual Studio ProgressBar 组件的替代方案。

引言
在本文中,我将向您展示一个自定义进度控件,我将其作为常规 Visual Studio ProgressBar 组件的替代方案。因此,我们将讨论
- 如何创建自定义组件
- 如何创建自定义事件和属性,以便在属性窗口中显示它们
- 如何使用 Paint 事件和图形进行绘图以及如何使用渐变画笔
背景
自定义控件继承自 UserControl
。UserControl
有一个名为 Paint
的事件,每次需要重绘控件时都会调用该事件。我们将使用此事件来绘制进度。创建此组件非常容易:我们只需要绘制一个椭圆(这将是剩余时间)和一个扇形(这将是经过的时间),如下面的代码所示
e.Graphics.FillEllipse(t_oBrushRemainingTime, t_oRectangle);
e.Graphics.FillPie(t_oBrushElapsedTime, t_oRectangle, -90f,
(float)(360 * m_iElapsedTime / m_iTotalTime));
大多数可以使用 Graphics 绘制的东西都需要一个矩形,它是绘制的边界。此矩形定义为与组件相同的大小。
Rectangle t_oRectangle = new Rectangle(0, 0, this.Width, this.Height);
为了创建渐变视觉效果,在绘制椭圆和扇形之前,定义了两个不同的画笔变量,以创建剩余时间和经过时间的不同视觉效果,如下所示
Brush t_oBrushRemainingTime = new LinearGradientBrush(t_oRectangle,
m_oColor1RemainingTime, m_oColor2RemainingTime, m_eLinearGradientMode);
Brush t_oBrushElapsedTime = new LinearGradientBrush(t_oRectangle,
m_oColor1ElapsedTime, m_oColor2ElapsedTime, m_eLinearGradientMode);
我们将跟踪两个变量:m_iElapsedTime
(它保存实际值 - 与 ProgressBar 中的 Value 属性相同)和 m_iTotalTime
(它保存时间量 - 与 ProgressBar 中的 Maximum 属性相同)。这两个变量用于计算表示经过时间的扇形的角度。众所周知,一个完整的圆有 360° 角。为了获得实际角度,我们只需进行 m_iElapsedTime
/ m_iTotalTime
* 360。
编写的唯一方法是 Increment()
方法。它有一个整数作为参数,该整数是要添加到 m_iElapsedTime
的数字。但在此之前,我们只需检查 m_iElapsedTime
是否大于 m_iTotalTime
。如果是,这意味着任务已完成,该方法返回。如果不是更大,则检查要添加的值加上 m_iElapsedTime
是否大于或等于 m_iTotalTime
。如果是,我们使 m_iElapsedTime
等于 m_iTotalTime
,更新控件并引发两个事件,PCIncremented
和 PCComplete
。如果不是更大,我们递增 m_iElapsedTime
,更新组件并引发 PCIncremented
事件。请参阅下面的代码
if (m_iElapsedTime > m_iTotalTime)
return;
if (m_iElapsedTime + a_iValue >= m_iTotalTime)
{
m_iElapsedTime = m_iTotalTime;
this.Refresh();
if (m_EventIncremented != null)
m_EventIncremented(this, null);
if (m_EventCompleted != null)
m_EventCompleted(this, null);
}
else
{
m_iElapsedTime += a_iValue;
this.Refresh();
if (m_EventIncremented != null)
m_EventIncremented(this, null);
}
为了创建这些自定义事件(PCIncremented
和 PCComplete
),我们创建了一个名为 EventHandler
的委托。有了这个委托,现在我们声明了两个类型为 EventHandler
的变量,分别名为 m_EventIncremented
和 m_EventCompleted
,带有修饰符 event,如下所示
public delegate void EventHandler(object sender, string message);
public event EventHandler m_EventIncremented;
public event EventHandler m_EventCompleted;
要引发事件,我们只需要检查变量是否已初始化,然后调用它。请参见下文
if (m_EventCompleted != null)
m_EventCompleted(this, null);
为了使这些事件可在属性窗口中的事件列表中浏览,我们需要为它们创建属性,并在其前面用括号括起来几个属性。主要的属性是 Category()
,它设置了在分类顺序中显示时的类别。另一个属性是 Description()
,它在属性窗口的底部显示简短的描述。两个自定义事件的属性及其各自的属性如下所示
[Category("ProgressCircle"), Description(
"Event raised everytime the component is incremented." +
"Author: Sergio Augusto Bitencourt Petrovcic")]
public event EventHandler PCIncremented
{
add { m_EventIncremented += new EventHandler(value); }
remove { m_EventIncremented -= new EventHandler(value); }
}
[Category("ProgressCircle"), Description(
"Event raised when the component get completed." +
"Author: Sergio Augusto Bitencourt Petrovcic")]
public event EventHandler PCCompleted
{
add { m_EventCompleted += new EventHandler(value); }
remove { m_EventCompleted -= new EventHandler(value); }
}
Using the Code
源代码有两个项目。第一个项目实现组件并生成一个程序集。第二个项目是一个测试项目,将第一个项目作为参考。因此,如果我们打开测试项目的主窗体并查看工具箱,我们将在那里看到该组件。我们只需要将其拖放到窗体中即可。
如果您想在自己的项目中使用此组件,您只需要将该组件添加到项目的工具箱中。只需右键单击工具箱,然后单击“选择项目”。然后单击“浏览”并搜索 ProgressCircle.dll。单击“打开”和“确定”。之后,只需将其拖放到您的窗体即可。
要配置组件,您可以使用属性窗口更改剩余时间和经过时间的渐变颜色,更改线性渐变模式,更改组件的总时间和经过时间,并设置事件。随着您的任务流程,只需调用 Increment()
并将要递增的值作为参数传递。就是这样!就这么简单。
历史
* 2008 年 4 月 - 首次发布。
版权所有 © 2007 Sergio A. B. Petrovcic。保留所有权利。未经我的明确许可,请勿发布到其他网站。根据本网站的政策和程序链接到本文。