跳过 FillEllipse (C#)

Skipping a FillEllipse (C#)

protected override void OnPaint(PaintEventArgs e)
{
    Graphics g = e.Graphics;
    SolidBrush brush = new SolidBrush(Color.Black);
    g.FillRectangle(brush, 35, 30, 140, 420);
    if (figure.Equals("red"))
    {                
        brush.Color = Color.Red;
        g.FillEllipse(brush, 35, 30, 140, 140);
        figure = "red";
    }
    else if (figure.Equals("yellow"))
    {               
        brush.Color = Color.Yellow;
        g.FillEllipse(brush, 35, 170, 140, 140);
        figure = "yellow";
    }
    else if (figure.Equals("green"))
    {              
        brush.Color = Color.ForestGreen;
        g.FillEllipse(brush, 35, 310, 140, 140);
        figure = "green";               
    }
}


private void Form1_Load(object sender, EventArgs e)
{

}

private void button1_Click(object sender, EventArgs e)
{
    if (figure.Equals("red"))
    {
        System.Threading.Thread.Sleep(750);
        figure = "yellow";
        Invalidate();
        System.Threading.Thread.Sleep(750);
        figure = "green";
        Invalidate();   
    }           

    else if (figure.Equals("green"))
    {
        System.Threading.Thread.Sleep(750);
        figure = "yellow";
        Invalidate();
        System.Threading.Thread.Sleep(750);
        figure = "red";
        Invalidate();               
    }


}

我正在编写一个简单的交通信号灯,我认为如果您可以按一次 "Switch" 按钮并从红色变为黄色再变为绿色,而不是每次都按下它,它会看起来更好。但是,现在当我 运行 程序时,它不是等待 0.75 秒绘制黄色然后再等待 0.75 秒绘制绿色,而是等待 1.5 秒然后直接从红色变为绿色,完全不显示黄色。

您的问题已在 Invalidate 方法

的 MSDN 页面中进行了说明

Calling the Invalidate method does not force a synchronous paint; to force a synchronous paint, call the Update method after calling the Invalidate method. When this method is called with no parameters, the entire client area is added to the update region.

所以需要在第一个Invalidate之后添加一个Update的调用

if (figure.Equals("red"))
{
    System.Threading.Thread.Sleep(750);
    figure = "yellow";
    Invalidate();
    Update();
    System.Threading.Thread.Sleep(750);
    figure = "green";
    Invalidate();   
}           

else if (figure.Equals("green"))
{
    System.Threading.Thread.Sleep(750);
    figure = "yellow";
    Invalidate();
    Update();
    System.Threading.Thread.Sleep(750);
    figure = "red";
    Invalidate();               
}

在第二次 Invalidate 之后不需要调用 Update,因为您的事件处理程序退出,因此系统可以接受对最后一次 Invalidate 的调用