我正在研究的这个小程序的目标是在选中 radiobutton1 时画一个红色圆圈,并在选中 radiobutton2 时画一个黑色圆圈。
下面是我的代码,这段代码的问题是当选中 radiobutton1 时,它确实画了红色圆圈,但是如果我单击 radiobutton2,那么所有的红色圆圈都会变成黑色。然后,如果再次选中单选按钮1,则所有点将再次变为红色。
如何在面板上保留两个色圈?
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++;
}
}
}
图形在 Windows 窗体中的工作方式是,Paint 方法重绘整个面板。
每次执行 paint 方法时,您已经绘制了每个点:这是正确的。
但是你无法记住哪个点应该是哪种颜色,所以当你画这幅画时,你所要做的就是单选按钮的当前值。添加圆圈时,您需要某种记录当前颜色的方法。
一种方法是定义一个 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
- 在 Paint
方法完成后保留 Graphics
对象是个坏主意。以后不一定仍然有效。始终只使用e.Graphics
。
我还用更简单的foreach
替换了您的while
循环.
如果我正确理解您的意图,您需要保留两个点列表,每种颜色一个。 然后,当您单击某处时,将单击的点放在相应的列表中(红色或黑色)。 然后,在 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的解决方案更好,因为它将所有圆圈保留在同一列表中,从而保持原始分层。 随意切换接受的答案。