如何将两个颜色圈保持在一起

时间:2016-04-28 21:12:16

标签: c# winforms graphics

我正在研究的这个小程序的目标是在检查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++;
        }
    }
}

2 个答案:

答案 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的解决方案更好,因为它将所有圆圈保持在同一个列表中,从而保持原始分层。随意切换接受的答案。