Link to home
Start Free TrialLog in
Avatar of dev775
dev775

asked on

Progress Bar Bound to Timer

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.
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

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

ASKER CERTIFIED SOLUTION
Avatar of Dmitry G
Dmitry G
Flag of New Zealand image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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! =)
Avatar of dev775
dev775

ASKER

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!
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...
Avatar of dev775

ASKER

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!
Avatar of dev775

ASKER

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!
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();
Avatar of dev775

ASKER

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.