We help IT Professionals succeed at work.

Progress Bar Bound to Timer

dev775
dev775 asked
on
Using C# I need to create a simple form that contains a progress bar that moves from 0% to 100% over a fixed, linear 20 second duration.  Above the progress bar I have a label control to display a message.  At 8 seconds and again at 15 seconds I need to change the text in the label.  When the timer times out I then want to display a button which will allow the user to close the form.  Assistance to write some simple code to achieve this function is much appreciated.
Comment
Watch Question

Mike TomlinsonHigh School Computer Science, Computer Applications, Digital Design, and Mathematics Teacher
Top Expert 2009

Commented:
There are so many ways to go about this...

Here is how I displayed the dialog:

    public partial class Form1 : Form
    {

        private void button1_Click(object sender, EventArgs e)
        {
            Form2 f2 = new Form2();
            f2.ShowDialog(this);
        }

    }

Here is the dialog:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form2 : Form
    {

        public Form2()
        {
            InitializeComponent();
            this.StartPosition = FormStartPosition.CenterParent;
        }

        protected override CreateParams CreateParams
        {
            get
            {
                const int CS_NOCLOSE = 0x200;
                CreateParams cp = base.CreateParams;
                cp.ClassStyle |= CS_NOCLOSE;
                return cp;
            }
        }

        private class TimedMessage
        {
            public string Message;
            public DateTime TargetTime;

            public TimedMessage(string Message, DateTime TargetTime)
            {
                this.Message = Message;
                this.TargetTime = TargetTime;
            }
        }

        private Timer tmr = new Timer();
        private DateTime EndTime;
        private DateTime StartTime;
        private double TotalMilliseconds;
        private List<TimedMessage> Messages = new List<TimedMessage>();

        private void Form2_Load(object sender, EventArgs e)
        {
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
            this.MinimizeBox = false;
            this.MaximizeBox = false;

            this.button1.Visible = false;
            this.tmr.Interval = 250;
            this.tmr.Enabled = false;
            this.tmr.Tick += new EventHandler(tmr_Tick);
            this.progressBar1.Value = 0;
            this.progressBar1.Minimum = 0;
            this.progressBar1.Maximum = 100;
            this.label1.Text = "Initial Message";
        }

        private void Form2_Shown(object sender, EventArgs e)
        {
            this.StartTime = DateTime.Now;
            this.EndTime = this.StartTime.AddSeconds(20);
            this.TotalMilliseconds = this.EndTime.Subtract(this.StartTime).TotalMilliseconds;
            Messages.Add(new TimedMessage("Message #1", this.StartTime.AddSeconds(8)));
            Messages.Add(new TimedMessage("Message #2", this.StartTime.AddSeconds(15)));
            tmr.Start();
        }

        void tmr_Tick(object sender, EventArgs e)
        {
            if (DateTime.Now <= this.EndTime)
            {
                Double p = DateTime.Now.Subtract(this.StartTime).TotalMilliseconds / this.TotalMilliseconds;
                this.progressBar1.Value = (int)(p * 100);
                
                TimedMessage tm;
                for (int i = 0; i < this.Messages.Count; i++)
                {
                    tm = Messages[i];
                    if (DateTime.Now >= tm.TargetTime)
                    {
                        this.label1.Text = tm.Message;
                        Messages.Remove(tm);
                        break;
                    }
                }
            }
            else
            {
                this.tmr.Stop();
                this.progressBar1.Value = this.progressBar1.Maximum;
                this.button1.Visible = true;
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.DialogResult = System.Windows.Forms.DialogResult.OK;
        }

    }
}

Open in new window

Senior Developer
Commented:
It's not very wise to compete with Idle_Mind but I just want to propose very simple straightforward solution

Of course, there are the following controls on a form:

           this.button1
            this.progressBar1
            this.progressBar1
            this.timer1.
            this.label1
   public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
           
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.button1.Visible = false;
            this.progressBar1.Minimum = 0;
            this.progressBar1.Maximum = 200;
            this.timer1.Interval = 100;// 1 second
            this.label1.Text = "";
        }
        private void button1_Click_1(object sender, EventArgs e)
        {
            this.Close();
        }

        private void Form1_Shown(object sender, EventArgs e)
        {
            this.timer1.Start();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            // increase progressbar
            if (this.progressBar1.Value < this.progressBar1.Maximum)
            {
                this.progressBar1.Value += 1;
            }
            // 5 seconds elapsed (25 ticks on a progre:
            if (this.progressBar1.Value  == 50)
            {
                this.label1.Text = "5 seconds";
            }
            else if (this.progressBar1.Value == 150)
            {
                this.label1.Text = "15 seconds";
            }
            else if (this.progressBar1.Value == this.progressBar1.Maximum)
            {
                this.timer1.Stop();
                this.label1.Text = "timer stopped";
                this.button1.Visible = true;
            }

        }



    }

Open in new window

Mike TomlinsonHigh School Computer Science, Computer Applications, Digital Design, and Mathematics Teacher
Top Expert 2009

Commented:
Lol...c'mon now!  I even started my post off with "There are so many ways to go about this..."

I love seeing multiple different approaches in a thread! =)

Author

Commented:
Idle Mind - thank you for such a complete response.  After copying your code and compiling I received an error for the "using System.Linq".  I am using VS2005.  I removed this line and then there were no complie errors but the program did not work.  I'm stuck - please help!
Mike TomlinsonHigh School Computer Science, Computer Applications, Digital Design, and Mathematics Teacher
Top Expert 2009

Commented:
No problem...where are you at?  Which part doesn't work?

Did you you wire up the button handlers to the correct methods in the code?
(Select the control, use the "lightning bolt" icon to find the event, then use the dropdown to pick the right method)

Does Form2 open when Button1 is pressed in Form1?

If Form2 opens, does the ProgressBar move?

etc...

Author

Commented:
Idle Mind... you are exactly correct, the solution was to "wire up" the handlers (as you put it!).  I didn't realize this was necessary - apparently when you drag-and-drop the controls using the VS designer this step isn't required.  I am learning very much - thanks.  Last question... suppose I want to eliminate form2 and have the little program just run upon lauching, then close when button1 is clicked?  Does this require many changes?  Thank you again for the great help!

Author

Commented:
anarki_jimbel: your solution worked as well.  I am examing the code from your solution and from Idle Mind and trying to learn some things.  Thanks very much!
Mike TomlinsonHigh School Computer Science, Computer Applications, Digital Design, and Mathematics Teacher
Top Expert 2009

Commented:
To change the "startup form" you double click on "program.cs" in the Solution Explorer in the top right of the IDE.  Then change the form that is passed into the Application.Run() call to that of the form you want to start the app with.

To make the app exit when the button is clicked you would just change it to:

    this.Close();

Author

Commented:
This was a very thorough response from both experts - one of the best I have received from many questions that I have posted to EE.