我正在研究的这个小程序的目标是在检查radiobutton1时绘制一个红色圆圈,并在检查radiobutton2时绘制一个黑色圆圈。
下面是我的代码,这段代码的问题是当检查radiobutton1时,它确实绘制了红色圆圈,但是如果我点击radiobutton2,那么所有的红色圆圈都会变成黑色。然后,如果再次检查radiobutton1,则所有点将再次变为红色。
如何在面板上保留两个色圈?
List<Point> points = new List<Point>();
Graphics g;
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
points.Add(e.Location);
panel1.Invalidate();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
int count = 0;
if (radioButton1.Checked)
{
g = e.Graphics;
while (count < points.Count())
{
g.FillEllipse(Brushes.Red, points[count].X, points[count].Y, 10, 10);
count++;
}
}
else if (radioButton2.Checked)
{
g = e.Graphics;
while (count < points.Count())
{
g.FillEllipse(Brushes.Black, points[count].X, points[count].Y, 10, 10);
count++;
}
}
}
答案 0 :(得分:3)
图形在Windows窗体中的工作方式是,Paint方法重绘整个面板。
每次执行paint方法时,您都在绘制每个点:这是正确的。
但是你无法记住哪个点应该是哪种颜色,所以当你进行绘画时你必须继续进行的是radiobuttons的当前值。添加圆圈时,您需要一些记录当前颜色的方法。
这样做的一种方法是定义一个Circle类,它存储圆的位置和颜色:
class Circle
{
public Point Location { get; set; }
public Brush Fill { get; set; }
}
然后代替points
成为List<Point>
,它可以是List<Circle>
,当您看到鼠标点击时,您可以添加新的Circle
而不是Point
var circle = new Circle()
{
Location = e.Location,
Fill = radioButton1.Checked ? Brushes.Red : Brushes.Black
};
points.Add(circle);
:
foreach (var circle in points)
{
e.Graphics.FillEllipse(circle.Fill, circle.Location.X, circle.Location.Y, 10, 10);
}
当你进行绘画时,你可以在绘制时检查每个圆圈的颜色 - 你所要做的就是:
Graphics g
请注意,您不需要成员级Graphics
- 在Paint
方法完成后保留e.Graphics
对象是个坏主意。它以后不一定有效。始终只使用while
。
我还将foreach
循环替换为更简单的public function getNameAttribute($name)
{
return trans($name);
}
。
答案 1 :(得分:2)
如果我理解你的意图,你需要保留两个点列表,每种颜色一个。然后,当您单击某处时,将单击的点放在适当的列表中(红色或黑色)。然后,在Paint
事件处理程序中,将条件代码替换为两个循环,一个遍历每个点列表(从红色列表中以红色绘制点,将黑色列表中的点绘制为黑色)。
代码:
List<Point> redPoints = new List<Point>();
List<Point> blackPoints = new List<Point>();
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
if (radioButton1.Checked)
redPoints.Add(e.Location);
else
blackPoints.Add(e.Location);
panel1.Invalidate();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
int count = 0;
Graphics g = e.Graphics;
foreach (Point p in redPoints)
{
g.FillEllipse(Brushes.Red, p.X, p.Y, 10, 10);
}
foreach (Point p in blackPoints)
{
g.FillEllipse(Brushes.Black, p.X, p.Y, 10, 10);
}
}
注意:如果你的圆圈相互重叠并且你关心保持分层顺序(首先点击的圆圈绘制),那么@ Blorgbeard的解决方案更好,因为它将所有圆圈保持在同一个列表中,从而保持原始分层。随意切换接受的答案。