在单击位置绘制一个新的圆位图,同时保留以前绘制的圆
Drawing a new circle bitmap at the click location while preserving previously drawn circles
我正在尝试使用位图绘制圆圈。
每次点击鼠标,我之前画的圆都会移动到新的位置。
我想要发生的是:每次我点击鼠标,一个新的圆在我点击的位置created/drawn,之前画的所有圆保持不动。
我正在使用以下代码:
using System;
using System.Drawing;
using System.Windows.Forms;
namespace multirectangle
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
}
Bitmap background;
Graphics scG;
Rectangle rectangleObj;
private Point clickCurrent = Point.Empty;
private Point clickPrev = Point.Empty;
private void Form1_Load(object sender, EventArgs e)
{
background = new Bitmap(Width, Height);
rectangleObj = new Rectangle(10, 10, 30, 30);
scG = Graphics.FromImage(background);
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
clickCurrent = PointToClient(Cursor.Position);
clickPrev = clickCurrent;
if (clickPrev == Point.Empty) return;
rectangleObj.X = clickPrev.X - rectangleObj.Height / 2;// +radius;
rectangleObj.Y = clickPrev.Y - rectangleObj.Width / 2;
Refresh();
}
protected override void OnPaint(PaintEventArgs pe)
{
pe.Graphics.DrawImage(Draw(), 0, 0);
}
public Bitmap Draw()
{
Graphics scG = Graphics.FromImage(background);
Pen myPen = new Pen(System.Drawing.Color.Red, 3);
scG.Clear(SystemColors.Control);
scG.DrawEllipse(myPen, rectangleObj);
return background;
}
}
}
我注意到一些事情。首先,在 Form1_MouseDown()
中,你有这个:
clickCurrent = PointToClient(Cursor.Position);
clickPrev = clickCurrent;
您甚至在保存之前就覆盖了旧位置 (clickPrev
)。如果你想保留这两个位置,你应该把它们放在一个简单的结构中,比如一个列表。当你得到一个新点时,只需 Add()
将它添加到列表中。然后,在您的 Draw()
例程中,遍历列表中的所有元素并将它们全部绘制出来。
如果您只想要两个职位——而且只有两个——只需像这样交换您的陈述:
clickPrev = clickCurrent;
clickCurrent = PointToClient(Cursor.Position);
而且您必须为绘图分配另一个矩形对象,尽管在 Draw()
例程中处理它更有意义。
交换以下语句的位置
clickCurrent = PointToClient(Cursor.Position);
clickPrev = clickCurrent;
我认为您在初始化 clickCurrent
后将 clickCurrent
分配给 clickPrevious
。需要反过来。
你的英语有点混乱。如果我对您的问题的理解正确,那么现在唯一绘制的是点击所在的新圆圈,并且您希望所有旧圆圈也保持不变?在这种情况下,有两种选择:
- 绘制前不要清除位图。
scG.Clear(SystemColors.Control);
将清除您刚刚绘制的位图。如果您删除该行并且不清除位图,那么下次您单击时,它将在最后一个位图的顶部绘制新的椭圆。
- 如果您每次都想要新鲜的 drawing/bitmap,则需要一份
rectangleObj
的列表。每次单击时,都会将该点添加到 rectangleObj
collection。然后在你的 draw 方法中,你将遍历 collection 并绘制所有它们。
请试试这个
Rectangle rectangleObj;
Bitmap background;
Graphics scG;
Pen myPen;
private void Form1_Load(object sender, EventArgs e)
{
rectangleObj = new Rectangle(10, 10, 30, 30);
background = new Bitmap(Width, Height);
scG = Graphics.FromImage(background);
myPen = new Pen(Color.Red, 3);
BackgroundImage = background;
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
var point = PointToClient(Cursor.Position);
rectangleObj.X = point.X - rectangleObj.Height / 2;
rectangleObj.Y = point.Y - rectangleObj.Width / 2;
scG.DrawEllipse(myPen, rectangleObj);
Refresh();
}
OnPaint
和 Draw
方法已删除。以及 clickCurrent
和 clickPrev
字段。
当您更改表单大小时(例如,最大化它),Bitmap 和 Graphics 保持不变,因此您会得到这种效果。为避免这种情况,您需要添加事件处理程序
private void Form1_SizeChanged(object sender, EventArgs e)
{
background = new Bitmap(Width, Height);
scG = Graphics.FromImage(background);
BackgroundImage = background;
}
请注意,每次调整表格大小时,之前绘制的所有内容都会被删除。如果这是不可取的,则需要采用不同的方法进行绘图。告诉我,我再举个例子。
我正在尝试使用位图绘制圆圈。
每次点击鼠标,我之前画的圆都会移动到新的位置。
我想要发生的是:每次我点击鼠标,一个新的圆在我点击的位置created/drawn,之前画的所有圆保持不动。
我正在使用以下代码:
using System;
using System.Drawing;
using System.Windows.Forms;
namespace multirectangle
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
}
Bitmap background;
Graphics scG;
Rectangle rectangleObj;
private Point clickCurrent = Point.Empty;
private Point clickPrev = Point.Empty;
private void Form1_Load(object sender, EventArgs e)
{
background = new Bitmap(Width, Height);
rectangleObj = new Rectangle(10, 10, 30, 30);
scG = Graphics.FromImage(background);
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
clickCurrent = PointToClient(Cursor.Position);
clickPrev = clickCurrent;
if (clickPrev == Point.Empty) return;
rectangleObj.X = clickPrev.X - rectangleObj.Height / 2;// +radius;
rectangleObj.Y = clickPrev.Y - rectangleObj.Width / 2;
Refresh();
}
protected override void OnPaint(PaintEventArgs pe)
{
pe.Graphics.DrawImage(Draw(), 0, 0);
}
public Bitmap Draw()
{
Graphics scG = Graphics.FromImage(background);
Pen myPen = new Pen(System.Drawing.Color.Red, 3);
scG.Clear(SystemColors.Control);
scG.DrawEllipse(myPen, rectangleObj);
return background;
}
}
}
我注意到一些事情。首先,在 Form1_MouseDown()
中,你有这个:
clickCurrent = PointToClient(Cursor.Position);
clickPrev = clickCurrent;
您甚至在保存之前就覆盖了旧位置 (clickPrev
)。如果你想保留这两个位置,你应该把它们放在一个简单的结构中,比如一个列表。当你得到一个新点时,只需 Add()
将它添加到列表中。然后,在您的 Draw()
例程中,遍历列表中的所有元素并将它们全部绘制出来。
如果您只想要两个职位——而且只有两个——只需像这样交换您的陈述:
clickPrev = clickCurrent;
clickCurrent = PointToClient(Cursor.Position);
而且您必须为绘图分配另一个矩形对象,尽管在 Draw()
例程中处理它更有意义。
交换以下语句的位置
clickCurrent = PointToClient(Cursor.Position);
clickPrev = clickCurrent;
我认为您在初始化 clickCurrent
后将 clickCurrent
分配给 clickPrevious
。需要反过来。
你的英语有点混乱。如果我对您的问题的理解正确,那么现在唯一绘制的是点击所在的新圆圈,并且您希望所有旧圆圈也保持不变?在这种情况下,有两种选择:
- 绘制前不要清除位图。
scG.Clear(SystemColors.Control);
将清除您刚刚绘制的位图。如果您删除该行并且不清除位图,那么下次您单击时,它将在最后一个位图的顶部绘制新的椭圆。 - 如果您每次都想要新鲜的 drawing/bitmap,则需要一份
rectangleObj
的列表。每次单击时,都会将该点添加到rectangleObj
collection。然后在你的 draw 方法中,你将遍历 collection 并绘制所有它们。
请试试这个
Rectangle rectangleObj;
Bitmap background;
Graphics scG;
Pen myPen;
private void Form1_Load(object sender, EventArgs e)
{
rectangleObj = new Rectangle(10, 10, 30, 30);
background = new Bitmap(Width, Height);
scG = Graphics.FromImage(background);
myPen = new Pen(Color.Red, 3);
BackgroundImage = background;
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
var point = PointToClient(Cursor.Position);
rectangleObj.X = point.X - rectangleObj.Height / 2;
rectangleObj.Y = point.Y - rectangleObj.Width / 2;
scG.DrawEllipse(myPen, rectangleObj);
Refresh();
}
OnPaint
和 Draw
方法已删除。以及 clickCurrent
和 clickPrev
字段。
当您更改表单大小时(例如,最大化它),Bitmap 和 Graphics 保持不变,因此您会得到这种效果。为避免这种情况,您需要添加事件处理程序
private void Form1_SizeChanged(object sender, EventArgs e)
{
background = new Bitmap(Width, Height);
scG = Graphics.FromImage(background);
BackgroundImage = background;
}
请注意,每次调整表格大小时,之前绘制的所有内容都会被删除。如果这是不可取的,则需要采用不同的方法进行绘图。告诉我,我再举个例子。