2012-03-26 76 views
1

我想在PictureBox中繪製一些小圖片(連續4 x 32px圖像),所以我應該重寫OnPaint方法或我需要使我的新組件擴展PictureBox? 我嘗試這樣做,它在Java中的工作,而不是在這裏:PictureBox與重寫OnPaint方法在C#

 this.pictureBox1 = new System.Windows.Forms.PictureBox() 
     { 
      protected override void OnPaint(PaintEventArgs e) 
      { 
       // If there is an image and it has a location, 
       // paint it when the Form is repainted. 
       Graphics g = e.Graphics; 

       // Draw a string on the PictureBox. 
       g.DrawString("Test, is that working?", 
       new Font("Arial", 10), System.Drawing.Brushes.Blue, new Point(30, 30)); 
      } 
     } 

InitializeComponent方法的全碼:

private void InitializeComponent() 
    { 
     System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Tools)); 
     this.pictureBox1 = new System.Windows.Forms.PictureBox() 
     { 
      protected override void OnPaint(PaintEventArgs e) 
      { 
       // If there is an image and it has a location, 
       // paint it when the Form is repainted. 
       Graphics g = e.Graphics; 

       // Draw a string on the PictureBox. 
       g.DrawString("Test, is that working?", 
       new Font("Arial", 10), System.Drawing.Brushes.Blue, new Point(30, 30)); 
      } 
     } 
     this.vscrollb = new System.Windows.Forms.VScrollBar(); 
     this.vScrollBar1 = new System.Windows.Forms.VScrollBar(); 
     ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); 
     this.SuspendLayout(); 
     // 
     // pictureBox1 
     // 
     this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Left; 
     this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image"))); 
     this.pictureBox1.InitialImage = null; 
     this.pictureBox1.Location = new System.Drawing.Point(0, 0); 
     this.pictureBox1.Name = "pictureBox1"; 
     this.pictureBox1.Size = new System.Drawing.Size(264, 262); 
     this.pictureBox1.TabIndex = 0; 
     this.pictureBox1.TabStop = false; 
     this.pictureBox1.Paint += new System.Windows.Forms.PaintEventHandler(this.pictureBox1_Paint); 
     // 
     // vscrollb 
     // 
     this.vscrollb.Location = new System.Drawing.Point(0, 0); 
     this.vscrollb.Name = "vscrollb"; 
     this.vscrollb.Size = new System.Drawing.Size(20, 80); 
     this.vscrollb.TabIndex = 0; 
     // 
     // vScrollBar1 
     // 
     this.vScrollBar1.Dock = System.Windows.Forms.DockStyle.Right; 
     this.vScrollBar1.Location = new System.Drawing.Point(267, 0); 
     this.vScrollBar1.Name = "vScrollBar1"; 
     this.vScrollBar1.Size = new System.Drawing.Size(17, 262); 
     this.vScrollBar1.TabIndex = 1; 
     this.vScrollBar1.Scroll += new System.Windows.Forms.ScrollEventHandler(this.HandleScroll); 
     // 
     // Tools 
     // 
     this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 
     this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 
     this.BackColor = System.Drawing.Color.Black; 
     this.ClientSize = new System.Drawing.Size(284, 262); 
     this.Controls.Add(this.vScrollBar1); 
     this.Controls.Add(this.pictureBox1); 
     this.Name = "Tools"; 
     this.Text = "Tools"; 
     ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); 
     this.ResumeLayout(false); 

    } 
+0

此代碼工作正常,問題是什麼? – ionden 2012-03-26 11:49:52

+0

我已將此添加到InitializeComponent方法。這是完整的代碼: – 2012-03-26 11:52:44

+8

@PiotrŁużecki:不要向'InitializeComponent'添加任何內容,因爲每次改變設置時,設計器都會覆蓋此方法。你可以在構造函數中調用「InitializeComponent」之後添加它。 – ChrFin 2012-03-26 11:54:13

回答

3

這僅僅是不合法的C#代碼。覆蓋像OnPaint()這樣的虛擬方法沒有問題,但是您只能從派生自PictureBox的類中這樣做。哪一個效果不錯,編譯完成後會自動將新控件添加到工具箱中,以便將它放在窗體上。

然而這不是必需的。您可以簡單地實施控件的Paint事件。你已經做了,你把它命名爲pictureBox1_Paint()。只需將您的代碼移到那裏。

其他重要的指針:從不編輯InitializeComponent()。它由設計師自動生成。只要修改表單的設計,就會丟失您在那裏編寫的任何代碼。這也是一種非常好的方式,使表單無法設計,當設計器加載表單時觸發異常。如果你重寫OnPaint(),那麼調用base.OnPaint()是很重要的。所以正常的PictureBox管道繼續工作。包括繪製圖像並引發Paint事件。確保至少遵循教程或閱讀關於Winforms編程的書籍,如果不這樣做,將會有大量的試用和大多數錯誤。

2

我建議從PictureBox繼承並添加您的邏輯在那裏。因此,您不必將邏輯添加到不屬於它的地方(父控件)。

public class SpecialPictureBox : PictureBox 
{ 
    protected override void OnPaint(PaintEventArgs e) 
    { 
     // if you want to execute the original PaintBox logic before you execute your own code, use the next line of code. 
     base.OnPaint(e); 

     // now do whatever you want 

    } 
} 

然後,您可以使用SpecialPictureBox無論你想要的地方。

編輯:添加base.OnPaint到的代碼示例

+0

所以我不能在沒有新課的情況下做到這一點?我是否必須打電話給一些像OnPaint或其他事件?我可以將此添加到工具箱嗎? – 2012-03-26 12:20:45

+0

你可以在不創建新類的情況下做到這一點,但我不會推薦它,因爲它是繼承添加特殊功能的典型OOP主體。除了OnPaint方法的新實現外,新類的行爲與以前完全相同。在編譯項目之後,新的控件將在工具箱中可用。 – MatthiasG 2012-03-26 13:03:12

+0

還有一件事:如果您重寫OnPaint方法,PictureBox將不會像之前那樣繪製圖片,因爲您覆蓋了邏輯。如果您希望pb在添加自己的邏輯之前執行自己的邏輯,則必須執行base.OnPaint(e)作爲重寫方法中的第一個調用。 – MatthiasG 2012-03-26 13:05:45