Search code examples
c#eventsevent-handlingtrafficevent-driven

How to get my Ellipse to flash with Timer.Interval on C#? (Emergency Red Light Simulation) (Using MonoDevelop on Ubuntu)


I cannot figure how to get the red light on my code to flash with respect to an interval that I have set for it.

I've tried to use Invalidate and Update, along with Refresh and none of them seems to work. I'm very new to C# and coding in general so it could be that the code is deeply flawed and if that is the case don't hesitate to yell at me.

public class UI: Form
{
    protected Label lights_title = new Label();
    protected Button pause, resume, exit;
    protected bool isPaint = true;
    public static System.Timers.Timer g_shock = new System.Timers.Timer();

    public UI()
    {
        // text initialization
        this.Text = "Chukwudi's Flashing Red Light";
        this.lights_title.Text = "Ikem's Emergency Lights!";
        // size initialization - determine the size of the UI Form
        this.lights_title.Size = new Size(700, 40);
        this.Size = new Size(1920, 1080);

        // location initialization (x,y) x pulls you right as the number increase, y pulls you down
        this.lights_title.Location = new Point(598, 60);

        // title config & background color
        this.lights_title.BackColor = Color.Coral;
        this.lights_title.TextAlign = (System.Drawing.ContentAlignment)HorizontalAlignment.Center;

        this.BackColor = Color.DimGray;

        Render();

        g_shock.Enabled = false;
        g_shock.Elapsed += ManageOnPaint;
        g_shock.Enabled = true;
        g_shock.Start();
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        Graphics shape = e.Graphics;
        if (isPaint)
        {
            shape.FillRectangle(Brushes.Black, new Rectangle(598, 90, 700, 700));
            shape.FillEllipse(Brushes.Red, new Rectangle(650, 140, 600, 600));
        }
        shape.FillRectangle(Brushes.Brown, new Rectangle(598, 785, 700, 60));
    }

    protected void ManageOnPaint(object sender, System.Timers.ElapsedEventArgs elapsed)
    {
        g_shock.Interval = 1000;
        Invalidate();
        Update();
        // turn something to true
    }
}

Solution

  • As Alex F pointed out, you're not toggling something to keep track of whether the control is red or not. And you're not painting anything in the timereventhandler. My suggestion is below, I left out bits that don't concern my point.

    private bool isRed;
    private static System.Timers.Timer g_shock = new System.Timers.Timer();
    
    public UI()
    {
        g_shock.Elapsed += ManageOnPaint;
        g_shock.Interval = 1000;
        g_shock.Start();
    }
    
    private void ManageOnPaint(object sender, System.Timers.ElapsedEventArgs elapsed)
    {
        if (isRed)
        {
            // Set ellipse color non red            
        }
        if (!isRed)
        {
            // Set ellipse color red
        }
    
        // Toggle isRed
        isRed = !isRed;
    }
    
    protected override void OnPaint(PaintEventArgs e)
    {
        /// paint ellipse with current ellipse color
    }