After button click event I want the program to draw a rectangle inside a picturebox. I don't know how to do that. So far I made only a rectangle outside of picture box like this. Afterwards I want to implement a flood fill algorithm to fill the rectangle with a color. That's why I have to have those bitmaps there.
按钮点击事件后,我希望程序在图片框内绘制一个矩形。我不知道该怎么做。到目前为止,我只在这样的图片框外面制作了一个矩形。之后我想实现泛洪填充算法用颜色填充矩形。这就是为什么我必须在那里有那些位图。
namespace howto_floodfill
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// The background image.
private Bitmap bm;
private Bitmap32 bm32;
// Make a rectangle
private void button1_Click(object sender, EventArgs e)
{
bm = new Bitmap(ClientSize.Width, ClientSize.Height);
using (Graphics gr = Graphics.FromImage(bm))
{
gr.Clear(Color.Silver);
gr.DrawRectangle(Pens.Black, 5, 5, 100, 60);
}
bm32 = new Bitmap32(bm);
this.BackgroundImage = bm;
}
}
}
3 个解决方案
#1
3
You can set a Paint
event handler for the PictureBox
that will allow you to do drawing over the top of the PictureBox
contents:
您可以为PictureBox设置Paint事件处理程序,以允许您在PictureBox内容的顶部进行绘制:
public partial class Form1 : Form
{
private bool _drawRectangle = false;
public Form1()
{
InitializeComponent();
pictureBox1.Paint += new PaintEventHandler(this.pictureBox1_Paint);
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (_drawRectangle) {
Graphics g = e.Graphics;
// use g to do your drawing
}
}
}
Just set _drawRectangle
to true
in your button click handler and call pictureBox1.Invalidate(). Doing your drawing in the Paint
event handler guarantees that whenever the PictureBox
is redrawn (say, because another window was over it), your rectangle gets drawn as well.
只需在按钮单击处理程序中将_drawRectangle设置为true,然后调用pictureBox1.Invalidate()。在Paint事件处理程序中进行绘制可确保每次重绘PictureBox时(例如,因为另一个窗口在其上方),您的矩形也会被绘制。
This will let you draw a rectangle over the PictureBox's contents. Rather than a flood fill algorithm, have you considered just using FillRectangle?
这将允许您在PictureBox的内容上绘制一个矩形。您是否只考虑使用FillRectangle而不是泛洪填充算法?
If you really want to do a flood fill, you'll have to work with an image as you're already doing, so you can read pixels from the image to know if a boundary has been reached. Then you could set the PictureBox's
Image
property with the resulting bitmap. (In this case, it wouldn't be necessary to do the graphics work in the Paint event handler, since the PictureBox
will make sure its Image
is drawn on every paint.)
如果你真的想要进行泛光填充,你将不得不使用你正在做的图像,这样你就可以从图像中读取像素,以了解是否已达到边界。然后,您可以使用生成的位图设置PictureBox的Image属性。 (在这种情况下,没有必要在Paint事件处理程序中执行图形工作,因为PictureBox将确保在每个绘图上绘制其Image。)
#2
2
You can use the control.CreateGraphics() method invoked from your picturebox.
您可以使用从图片框调用的control.CreateGraphics()方法。
namespace WindowsFormsApplication_Test
{
public partial class Form1 : Form
{
private Bitmap bm;
public Form1()
{
InitializeComponent();
bm = new Bitmap(pB.ClientRectangle.Width, pB.ClientRectangle.Height);
}
private void btn_Click(object sender, EventArgs e)
{
Graphics gF = pB.CreateGraphics();
gF.Clear(Color.Silver);
gF.DrawRectangle(Pens.Black, 5, 5, 100, 60);
}
private void button1_Click(object sender, EventArgs e)
{
Graphics gF = Graphics.FromImage(bm);
gF.Clear(Color.Silver);
gF.DrawRectangle(Pens.Black, 5, 5, 100, 60);
pB.Image = bm;
}
}
}
btn_click() is an example of getting the graphics context from the control and drawing directly.
btn_click()是直接从控件和绘图中获取图形上下文的示例。
Form prior to clicking...
点击之前的表格...
Clicking the button will draw on the control directly - note that by default it gives you the clientRectangle portion of the control, which is nice...
单击该按钮将直接在控件上绘制 - 请注意,默认情况下它会为您提供控件的clientRectangle部分,这很好......
Clicking on the button gives you this.
点击按钮就可以了解这一点。
Now I resized the form.
现在我调整了表格的大小。
Unfortunately, drawing on the form this way makes you responsible for redrawing your data any time the window is invalidated.
不幸的是,以这种方式绘制表单会使您负责在窗口失效时重绘数据。
You can also just set the Image property of the form to be your private bitmap and then the framework handles redrawing for you. This is shown in the button1_Click() method.
您也可以将表单的Image属性设置为您的私有位图,然后框架为您处理重绘。这在button1_Click()方法中显示。
You can still draw directly on the control if you wish, but you'll need to hook into the control events and redraw when the form does. For example, adding a flag as a private bool to the form class, overriding the OnPaint method, and adding code to your button event to swap the flag. Rather than duplicating the drawing code in the button event, you can just flip the flag and call this.Invalidate();
如果愿意,您仍然可以直接在控件上绘制,但是您需要挂钩控件事件并在表单执行时重绘。例如,将标志作为私有bool添加到表单类,重写OnPaint方法,并将代码添加到按钮事件以交换标志。您可以只是翻转标志并调用this.Invalidate();而不是在按钮事件中复制绘图代码。
public partial class Form1 : Form
{
private Bitmap bm;
private bool bDrawn = false;
public Form1()
{
InitializeComponent();
bm = new Bitmap(pB.ClientRectangle.Width, pB.ClientRectangle.Height);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (bDrawn)
{
Graphics gF = pB.CreateGraphics();
gF.Clear(Color.Silver);
gF.DrawRectangle(Pens.Black, 5, 5, 100, 60);
}
}
private void btn_Click(object sender, EventArgs e)
{
//Graphics gF = pB.CreateGraphics();
//gF.Clear(Color.Silver);
///gF.DrawRectangle(Pens.Black, 5, 5, 100, 60);
bDrawn = true;
this.Invalidate();
}
#3
0
Assign the created bitmap to the Image property of the picture box. Now you can draw whatever you want on the bitmap, and then manipulate it's data.
将创建的位图分配给图片框的Image属性。现在,您可以在位图上绘制任何想要的内容,然后操纵它的数据。
namespace howto_floodfill {
public partial class Form1 : Form {
private Bitmap bitmap;
public Form1() {
InitializeComponent();
this.bitmap = new Bitmap(100, 100);
this.pictureBox1.Image = this.bitmap;
}
// Make a rectangle
private void button1_Click(object sender, EventArgs e) {
if (this.bitmap != null) {
this.bitmap.Dispose();
}
this.bitmap = new Bitmap(ClientSize.Width, ClientSize.Height);
using (Graphics gr = Graphics.FromImage(bitmap)) {
gr.Clear(Color.Silver);
gr.DrawRectangle(Pens.Black, 5, 5, 100, 60);
}
this.pictureBox1.Image = this.bitmap;
}
}
}
Note that you may not need to re-create the bitmap each time if it has a fixed size.
请注意,如果位图具有固定大小,则可能不需要每次都重新创建位图。
#1
3
You can set a Paint
event handler for the PictureBox
that will allow you to do drawing over the top of the PictureBox
contents:
您可以为PictureBox设置Paint事件处理程序,以允许您在PictureBox内容的顶部进行绘制:
public partial class Form1 : Form
{
private bool _drawRectangle = false;
public Form1()
{
InitializeComponent();
pictureBox1.Paint += new PaintEventHandler(this.pictureBox1_Paint);
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (_drawRectangle) {
Graphics g = e.Graphics;
// use g to do your drawing
}
}
}
Just set _drawRectangle
to true
in your button click handler and call pictureBox1.Invalidate(). Doing your drawing in the Paint
event handler guarantees that whenever the PictureBox
is redrawn (say, because another window was over it), your rectangle gets drawn as well.
只需在按钮单击处理程序中将_drawRectangle设置为true,然后调用pictureBox1.Invalidate()。在Paint事件处理程序中进行绘制可确保每次重绘PictureBox时(例如,因为另一个窗口在其上方),您的矩形也会被绘制。
This will let you draw a rectangle over the PictureBox's contents. Rather than a flood fill algorithm, have you considered just using FillRectangle?
这将允许您在PictureBox的内容上绘制一个矩形。您是否只考虑使用FillRectangle而不是泛洪填充算法?
If you really want to do a flood fill, you'll have to work with an image as you're already doing, so you can read pixels from the image to know if a boundary has been reached. Then you could set the PictureBox's
Image
property with the resulting bitmap. (In this case, it wouldn't be necessary to do the graphics work in the Paint event handler, since the PictureBox
will make sure its Image
is drawn on every paint.)
如果你真的想要进行泛光填充,你将不得不使用你正在做的图像,这样你就可以从图像中读取像素,以了解是否已达到边界。然后,您可以使用生成的位图设置PictureBox的Image属性。 (在这种情况下,没有必要在Paint事件处理程序中执行图形工作,因为PictureBox将确保在每个绘图上绘制其Image。)
#2
2
You can use the control.CreateGraphics() method invoked from your picturebox.
您可以使用从图片框调用的control.CreateGraphics()方法。
namespace WindowsFormsApplication_Test
{
public partial class Form1 : Form
{
private Bitmap bm;
public Form1()
{
InitializeComponent();
bm = new Bitmap(pB.ClientRectangle.Width, pB.ClientRectangle.Height);
}
private void btn_Click(object sender, EventArgs e)
{
Graphics gF = pB.CreateGraphics();
gF.Clear(Color.Silver);
gF.DrawRectangle(Pens.Black, 5, 5, 100, 60);
}
private void button1_Click(object sender, EventArgs e)
{
Graphics gF = Graphics.FromImage(bm);
gF.Clear(Color.Silver);
gF.DrawRectangle(Pens.Black, 5, 5, 100, 60);
pB.Image = bm;
}
}
}
btn_click() is an example of getting the graphics context from the control and drawing directly.
btn_click()是直接从控件和绘图中获取图形上下文的示例。
Form prior to clicking...
点击之前的表格...
Clicking the button will draw on the control directly - note that by default it gives you the clientRectangle portion of the control, which is nice...
单击该按钮将直接在控件上绘制 - 请注意,默认情况下它会为您提供控件的clientRectangle部分,这很好......
Clicking on the button gives you this.
点击按钮就可以了解这一点。
Now I resized the form.
现在我调整了表格的大小。
Unfortunately, drawing on the form this way makes you responsible for redrawing your data any time the window is invalidated.
不幸的是,以这种方式绘制表单会使您负责在窗口失效时重绘数据。
You can also just set the Image property of the form to be your private bitmap and then the framework handles redrawing for you. This is shown in the button1_Click() method.
您也可以将表单的Image属性设置为您的私有位图,然后框架为您处理重绘。这在button1_Click()方法中显示。
You can still draw directly on the control if you wish, but you'll need to hook into the control events and redraw when the form does. For example, adding a flag as a private bool to the form class, overriding the OnPaint method, and adding code to your button event to swap the flag. Rather than duplicating the drawing code in the button event, you can just flip the flag and call this.Invalidate();
如果愿意,您仍然可以直接在控件上绘制,但是您需要挂钩控件事件并在表单执行时重绘。例如,将标志作为私有bool添加到表单类,重写OnPaint方法,并将代码添加到按钮事件以交换标志。您可以只是翻转标志并调用this.Invalidate();而不是在按钮事件中复制绘图代码。
public partial class Form1 : Form
{
private Bitmap bm;
private bool bDrawn = false;
public Form1()
{
InitializeComponent();
bm = new Bitmap(pB.ClientRectangle.Width, pB.ClientRectangle.Height);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (bDrawn)
{
Graphics gF = pB.CreateGraphics();
gF.Clear(Color.Silver);
gF.DrawRectangle(Pens.Black, 5, 5, 100, 60);
}
}
private void btn_Click(object sender, EventArgs e)
{
//Graphics gF = pB.CreateGraphics();
//gF.Clear(Color.Silver);
///gF.DrawRectangle(Pens.Black, 5, 5, 100, 60);
bDrawn = true;
this.Invalidate();
}
#3
0
Assign the created bitmap to the Image property of the picture box. Now you can draw whatever you want on the bitmap, and then manipulate it's data.
将创建的位图分配给图片框的Image属性。现在,您可以在位图上绘制任何想要的内容,然后操纵它的数据。
namespace howto_floodfill {
public partial class Form1 : Form {
private Bitmap bitmap;
public Form1() {
InitializeComponent();
this.bitmap = new Bitmap(100, 100);
this.pictureBox1.Image = this.bitmap;
}
// Make a rectangle
private void button1_Click(object sender, EventArgs e) {
if (this.bitmap != null) {
this.bitmap.Dispose();
}
this.bitmap = new Bitmap(ClientSize.Width, ClientSize.Height);
using (Graphics gr = Graphics.FromImage(bitmap)) {
gr.Clear(Color.Silver);
gr.DrawRectangle(Pens.Black, 5, 5, 100, 60);
}
this.pictureBox1.Image = this.bitmap;
}
}
}
Note that you may not need to re-create the bitmap each time if it has a fixed size.
请注意,如果位图具有固定大小,则可能不需要每次都重新创建位图。