本文提供如何建立自定義 UserControl 以建立平滑的 Scrolling ProgressBar 控件的相關信息。
原始產品版本: Visual C#
原始 KB 編號: 323116
摘要
本文示範如何建立簡單的自定義UserControl,以建立平滑的Scrolling 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 Forms 控件連結庫]。
在 [ 名稱] 方塊中,輸入 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 Forms 應用程式],然後按兩下 [確定]。
請遵循下列步驟,將 SmoothProgressBar 控件的兩個實例新增至窗體:
在 [工具] 功能表中按一下 [選擇工具箱項目]。
按兩下 [.NET Framework 元件] 索引標籤。
按兩下 [瀏覽],然後找出您在 [建立自定義 ProgressBar 控件] 區段中建立的SmoothProgressBar.dll檔案。
按一下 [確定]。
注意
SmoothProgressBar 控件會新增至工具箱。
將 SmoothProgressBar 控制件的兩個實例從工具箱拖曳到 Windows 應用程式專案的預設表單。
將定時器控件從工具箱拖曳至表單。
將下列程式代碼新增至
TickTimer 控制項的事件:if (this.smoothProgressBar1.Value > 0) { this.smoothProgressBar1.Value--; this.smoothProgressBar2.Value++; } else { this.timer1.Enabled = false; }將按鈕控件從工具箱拖曳至表單。
將下列程式代碼新增至
ClickButton 控制的事件:this.smoothProgressBar1.Value = 100; this.smoothProgressBar2.Value = 0; this.timer1.Interval = 1; this.timer1.Enabled = true;在 [ 偵錯] 功能表上,單擊 [ 開始 ] 以執行範例專案。
按一下 按鈕。
注意
這兩個進度指標會顯示文字 進度。 其中一個進度指標會以遞增的方式顯示進度,另一個進度指示器則會以遞減或倒數的方式顯示進度。