本文介绍如何创建自定义 UserControl 以创建平滑滚动 ProgressBar 控件。
原始产品版本: Visual C#
原始 KB 数: 323116
总结
本文演示如何创建一个简单的自定义 UserControl 来创建平滑滚动的 ProgressBar 控件。
在早期版本的 ProgressBar 控件(如随 Microsoft Windows Common Controls ActiveX 控件一起提供的版本)中,可以在两个不同的视图中查看进度。 若要控制这些视图,请使用 Scrolling 属性,其中包括标准和平滑设置。 平滑滚动生成表示进度的纯色块,标准滚动显示为分段,由一系列小块或矩形组成。
Microsoft Visual C# 附带的 ProgressBar 控件仅支持标准设置。
本文中的示例代码演示如何创建支持以下属性的控件:
- 最小值:此属性获取或设置进度的有效值范围的较低值。 此属性的默认值为零(0);不能将此属性设置为负值。
- 最大值:此属性获取或设置进度的有效值范围的上限值。 此属性的默认值为 100。
- 值:此属性获取或设置当前进度级别。 该值必须位于 Minimum 和 Maximum 属性定义的范围内。
- ProgressBarColor:此属性获取或设置进度栏的颜色。
创建自定义 ProgressBar 控件
按照以下步骤在 Visual C# 中创建新的 Windows 控件库项目:
启动 Microsoft Visual Studio。
在 “文件” 菜单上,指向 “新建” ,然后单击 “项目” 。
在“新建项目”对话框中,单击“项目类型”下的“Visual C#”,然后单击“模板”下的“Windows 窗体控件库”。
在 “名称 ”框中,键入 SmoothProgressBar,然后单击“ 确定”。
在 项目资源管理器中,将默认类模块从 UserControl1.cs 重命名为 SmoothProgressBar.cs。
在 UserControl 对象的“属性”窗口中,将 Name 属性从 UserControl1 更改为 SmoothProgressBar。
此时,通常继承自该控件的类,然后添加附加功能以扩展现有控件。 但是,ProgressBar 类是密封的,无法继承。 因此,必须从头开始生成控件。
在派生自 UserControl 的类中 ,将以下代码添加到SmoothProgressBar.cs 文件中。
int min = 0;// Minimum value for progress range int max = 100;// Maximum value for progress range int val = 0;// Current progress Color BarColor = Color.Blue;// Color of progress meter protected override void OnResize(EventArgs e) { // Invalidate the control to get a repaint. this.Invalidate(); } protected override void OnPaint(PaintEventArgs e) { Graphics g = e.Graphics; SolidBrush brush = new SolidBrush(BarColor); float percent = (float)(val - min) / (float)(max - min); Rectangle rect = this.ClientRectangle; // Calculate area for drawing the progress. rect.Width = (int)((float)rect.Width * percent); // Draw the progress meter. g.FillRectangle(brush, rect); // Draw a three-dimensional border around the control. Draw3DBorder(g); // Clean up. brush.Dispose(); g.Dispose(); } public int Minimum { get { return min; } set { // Prevent a negative value. if (value < 0) { value = 0; } // Make sure that the minimum value is never set higher than the maximum value. if (value > max) { max = value; } min = value; // Ensure value is still in range if (val < min) { val = min; } // Invalidate the control to get a repaint. this.Invalidate(); } } public int Maximum { get { return max; } set { // Make sure that the maximum value is never set lower than the minimum value. if (value < min) { min = value; } max = value; // Make sure that value is still in range. if (val > max) { val = max; } // Invalidate the control to get a repaint. this.Invalidate(); } } public int Value { get { return val; } set { int oldValue = val; // Make sure that the value does not stray outside the valid range. if (value < min) { val = min; } else if (value > max) { val = max; } else { val = value; } // Invalidate only the changed area. float percent; Rectangle newValueRect = this.ClientRectangle; Rectangle oldValueRect = this.ClientRectangle; // Use a new value to calculate the rectangle for progress. percent = (float)(val - min) / (float)(max - min); newValueRect.Width = (int)((float)newValueRect.Width * percent); // Use an old value to calculate the rectangle for progress. percent = (float)(oldValue - min) / (float)(max - min); oldValueRect.Width = (int)((float)oldValueRect.Width * percent); Rectangle updateRect = new Rectangle(); // Find only the part of the screen that must be updated. if (newValueRect.Width > oldValueRect.Width) { updateRect.X = oldValueRect.Size.Width; updateRect.Width = newValueRect.Width - oldValueRect.Width; } else { updateRect.X = newValueRect.Size.Width; updateRect.Width = oldValueRect.Width - newValueRect.Width; } updateRect.Height = this.Height; // Invalidate the intersection region only. this.Invalidate(updateRect); } } public Color ProgressBarColor { get { return BarColor; } set { BarColor = value; // Invalidate the control to get a repaint. this.Invalidate(); } } private void Draw3DBorder(Graphics g) { int PenWidth = (int)Pens.White.Width; g.DrawLine(Pens.DarkGray, new Point(this.ClientRectangle.Left, this.ClientRectangle.Top), new Point(this.ClientRectangle.Width - PenWidth, this.ClientRectangle.Top)); g.DrawLine(Pens.DarkGray, new Point(this.ClientRectangle.Left, this.ClientRectangle.Top), new Point(this.ClientRectangle.Left, this.ClientRectangle.Height - PenWidth)); g.DrawLine(Pens.White, new Point(this.ClientRectangle.Left, this.ClientRectangle.Height - PenWidth), new Point(this.ClientRectangle.Width - PenWidth, this.ClientRectangle.Height - PenWidth)); g.DrawLine(Pens.White, new Point(this.ClientRectangle.Width - PenWidth, this.ClientRectangle.Top), new Point(this.ClientRectangle.Width - PenWidth, this.ClientRectangle.Height - PenWidth)); }
在“生成”菜单上,单击“生成解决方案”以编译项目。
创建示例客户端应用程序
在 “文件” 菜单上,指向 “新建” ,然后单击 “项目” 。
在“添加新项目”对话框中,单击“项目类型”下的“Visual C#”,单击“模板”下的“Windows 窗体应用程序”,然后单击“确定”。
按照以下步骤将 SmoothProgressBar 控件的两个实例添加到窗体中:
在 “工具” 菜单上,单击 “选择工具箱项” 。
单击“.NET Framework 组件”选项卡。
单击“浏览”,然后找到在“创建自定义 ProgressBar”控件部分中创建的SmoothProgressBar.dll文件。
单击 “确定” 。
注意
SmoothProgressBar 控件将添加到工具箱中。
将 SmoothProgressBar 控件的两个实例从工具箱拖到 Windows 应用程序项目的默认窗体。
将计时器控件从工具箱拖动到窗体。
将以下代码添加到
Tick
Timer 控件的事件:if (this.smoothProgressBar1.Value > 0) { this.smoothProgressBar1.Value--; this.smoothProgressBar2.Value++; } else { this.timer1.Enabled = false; }
将按钮控件从工具箱拖动到窗体。
将以下代码添加到
Click
Button 控件的事件:this.smoothProgressBar1.Value = 100; this.smoothProgressBar2.Value = 0; this.timer1.Interval = 1; this.timer1.Enabled = true;
在“调试”菜单上,单击“开始”以运行示例项目。
单击“”按钮。
注意
两个进度指示器显示文本 进度。 一个进度指示器以递增方式显示进度,另一个进度指示器以递减或倒计时方式显示进度。