2013-06-18 41 views
0

我創建了一個派生自System.Windows.Forms.ProgressBar的類。我接着MSDN通知的方法:派生自System.Windows.Forms.ProgressBar的類沒有得到它的覆蓋OnPaint

  • 添加用戶控件到您的項目
  • 打開用戶控制
  • 的代碼,而不是從System.Windows.Forms.UserControl獲得它,從進度派生。

而且我重寫的OnPaint,這樣我就可以畫它自己:

protected override void OnPaint(PaintEventArgs e) 
{ 
    base.OnPaint(e); 
    // etc, do your own painting. 

然而,這種功能不會被調用。斷點不會在這裏突破。進度條正常繪製。我錯過了什麼?

+0

進度條是本地Windows控件,它自己繪畫。 ProgressBar類只是一個小的.NET包裝類,它具有UserPaint樣式關閉,就像它爲所有本地Windows控件所做的一樣。你正在犯一個經典錯誤,不解釋爲什麼你認爲你需要這個。 –

回答

2

以下過程與MSDN提出的完全相同。進度條有一個OnPaint函數,所以根據MSDN你的OnPaint應該被調用。

它沒有被調用的原因是因爲你必須聲明你將自己繪製你的控件。在舊的MFC中,這被稱爲OwnerDrawn。爲了告訴系統你想自己繪製你的控件,你必須改變控件的樣式。這是通過使用Control.SetStyle完成的:

public partial class ColorProgressBar : System.Windows.Forms.ProgressBar 
{ 
    public ColorProgressBar() 
    { 
     InitializeComponent(); 
     this.SetStyle(ControlStyles.UserPaint, true); 
     // etc, other initializations 
    } 

這將保證您的OnPaint將被調用。

作爲一個完整的ColorProgressBar的例子。這個類的代碼可以在其他地方找到,但是在這裏它被重寫爲來自System.Windows.Forms.ProgressBar的派生類。這使得代碼更小。除了你有一個進度條的所有功能。

此進度條沒有條形的純色,而是兩種顏色之間的漸變色。它可以像使用其他控件一樣使用工具箱添加。可以像更改Progressbar的屬性一樣更改屬性。在屬性窗口的底部,您會看到額外的屬性。

來創建它:

  • 創建項目
  • 在解決方案Exploser - 添加 - 用戶控件,給它一個名稱,例如ColorProgressBar
  • 打開ColorProgressBar在編輯器中
  • 代碼
  • 將基類從UserControl更改爲System.Windows.Forms.ProgressBar
  • 將類更改爲您的需要,請參閱下面的示例

最重要的功能是OnPaint,它將改變ProgressBar的外觀。其餘的是很簡單的:

  • 添加兩個屬性來描述漸變色
  • 在構造函數中的SetStyle如上所述,以確保您的OnPaint被稱爲:

    公共部分類ColorProgressBar:系統.Windows.Forms。ProgressBar { public color BarColorOutside {get;組; } public Color BarColorCenter {get;組; }

    public ColorProgressBar() 
    { 
        BarColorOutside = Color.Black; 
        BarColorCenter = Color.Yellow; 
        InitializeComponent(); 
        this.SetStyle(ControlStyles.UserPaint, true); 
    } 
    
    protected override void OnPaint(PaintEventArgs e) 
    { 
        base.OnPaint(e); 
        // your own painting will be added later 
    } 
    

現在檢查此基礎工程:

  • 構建
  • 創建一個表單。將進度條添加到表格
  • 使用屬性爲進度條指定一個值,並使用初始顏色
  • 調試以檢查您的onPaint是否被調用。

現在onPaint。填充的Progressbar部分將填充漸變顏色。爲此,我們需要知道進度條的填充寬度和高度。我們可以製作兩個矩形:一個填充上半部分,另一個填充下半部分。填充將使用漸變畫筆完成:從barColorOutside到barColorCenter的上半部分,從barColorCenter到barColorOutside的下半部分。這樣中心顏色將位於進度條的中心。

protected override void OnPaint(PaintEventArgs e) 
{ 
    base.OnPaint(e); 

    // the part that has to be filled with a colored progress: 
    int fillWidth = (Width * Value)/(Maximum - Minimum); 
    if (fillWidth == 0) 
    { // nothing to fill 
     return; 
    } 

    // the two rectangles: 
    Rectangle topRect = new Rectangle(0, 0, fillWidth, Height/2); 
    Rectangle bottomRect = new Rectangle(0, Height/2, fillWidth, Height); 

    // Paint upper half: the gradient fills the complete topRect, 
    // from background color to foreground color 
    LinearGradientBrush brush = new LinearGradientBrush(topRect, BarColorOutside, 
     BarColorCenter, LinearGradientMode.Vertical); 
    e.Graphics.FillRectangle(brush, topRect); 
    brush.Dispose(); 

    // paint lower half: gradient fills the complete bottomRect, 
    // from foreground color to background color 
    brush = new LinearGradientBrush(bottomRect, BarColorCenter, BarColorOutside, 
     LinearGradientMode.Vertical); 
    e.Graphics.FillRectangle(brush, bottomRect); 
    brush.Dispose(); 

    // we have missed one line in the center: draw a line: 
    Pen pen = new Pen(BarColorCenter); 
    e.Graphics.DrawLine(pen, new Point(0, topRect.Bottom), 
     new Point(fillWidth, topRect.Bottom)); 
    pen.Dispose(); 

    // if style is blocks, draw vertical lines to simulate blocks 
    if (Style == ProgressBarStyle.Blocks) 
    { 
     int seperatorWidth = (int)(this.Height * 0.67); 
     int NrOfSeparators = (int)(fillWidth/seperatorWidth); 
     Color sepColor = ControlPaint.LightLight(BarColorCenter); 

     for (int i = 1; i <= NrOfSeparators; i++) 
     { 
      e.Graphics.DrawLine(new Pen(sepColor, 1), 
      seperatorWidth * i, 0, seperatorWidth * i, this.Height); 
     } 
    } 
}