2012-03-26 2 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

+0

Я добавил это к методу InitializeComponent. Это полный код: –

+8

@ PiotrŁużecki: НЕ добавляйте ничего в «InitializeComponent», так как этот метод будет перезаписываться Дизайнером каждый раз, когда он что-то изменяет. Вы можете добавить его «после того, как в конструкторе вызывается« InitializeComponent ». – ChrFin

ответ

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 везде, где захотите.

Edit: добавил base.OnPaint закодировать пример

+0

Так что я не могу сделать это без создания нового класса? Нужно ли мне называть некоторые события, такие как OnPaint или что-то еще? Могу ли я добавить это в панель инструментов? –

+0

Вы можете сделать это, не создавая новый класс, но я бы не рекомендовал его, так как это типичный руководитель ООП, чтобы наследовать, чтобы добавить специальные функции. Поведение вашего нового класса точно такое же, как и раньше, кроме новой реализации метода OnPaint. После компиляции проекта новый элемент управления будет доступен в панели инструментов. – MatthiasG

+0

Еще одна вещь: если вы переопределите метод OnPaint, PictureBox не будет рисовать картинку, как раньше, потому что вы перевернули логику. Если вы хотите, чтобы pb выполнил свою собственную логику до того, как вы добавите свой, вы должны выполнить base.OnPaint (e) в качестве первого вызова в вашем переопределенном методе. – MatthiasG