Lance Hietpas
Lance Hietpas

Reputation: 361

Passing values from one place to another

This is my first attempt at learning classes in any language. I am trying to create a Windows Form Project that is a stop watch. I've created a class that has a StartClock method that starts a stopwatch, I then put the elapsed time into a timespan variable. I then take a elapsedTime string and set it equal to a formatted string with the time span varibles. Code Below.

 public class CStopWatch
{

     Stopwatch sw = new Stopwatch();

    private DateTime startTime;

    private DateTime stopTime;

    private String elapsedTime;

    public String ElapsedTime
    {
        get
        { 
            return elapsedTime; 
        }


    }

     public String StartClock()
     {

         sw.Start();
         TimeSpan ts = sw.Elapsed;
         elapsedTime = String.Format("{0:00}:{1:00}:{2:00}",
        ts.Hours, ts.Minutes, ts.Seconds / 10);
         return elapsedTime;


     }

    public void StopClock()
     {
        // sw.Stop();
     }

}

On the Windows Form I call a new instance of my CStopwatch class and then on the start button click event I start my forms timer, call my StartClock method, and then set my time interval to every second.

In my Timer tick event I set my label to display the elapsed time string variable. When I run this I do not get any errors, but the label does not change. Below is my Windows Form Code.

 public partial class Form1 : Form
{
   // string elapsedTime;

   // public string elapsedTime { get { return elapsedTime; } }

    CStopWatch sw = new CStopWatch();

    public Form1()
    {
        InitializeComponent();
    }

    private void lblTime_Click(object sender, EventArgs e)
    {

    }


    private void btnStart_Click(object sender, EventArgs e)
    {
        timer.Enabled = true;
        sw.StartClock();
        timer.Interval = 1000;

        //Testing without using classes
        /*
        timer.Enabled = true;
        sw.Start();
        timer.Interval = 1000;
        TimeSpan ts = sw.Elapsed;
        string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}",
        ts.Hours, ts.Minutes, ts.Seconds / 10);
      */

    }

    private void Form1_Load(object sender, EventArgs e)
    {

    }

    private void timer_Tick(object sender, EventArgs e)
    {

        lblTime.Text = sw.ElapsedTime;


    }
}

I'm sure I'm missing something or doing something stupid, but all my google fu has not lead me to the answer yet. Thanks in advance.

Upvotes: 3

Views: 84

Answers (6)

d.moncada
d.moncada

Reputation: 17402

I believe there are some issues with your current implementation. Update your WinForms code-behind so that StartClock happens after you set the Interval. Also, if the Timer is happening on another Thread, you will want to Invoke the control. Lastly, you need to update the ElapsedTime whenever the Tick occurs.

public partial class Form1 : Form
{
    CStopWatch sw = new CStopWatch();

    public Form1()
    {
        InitializeComponent();
    }

    private void btnStart_Click(object sender, EventArgs e)
    {
        timer.Interval = 1000;
        timer.Enabled = true;

        lblTime.Text = sw.StartClock();
    }

    private void Form1_Load(object sender, EventArgs e)
    {

    }

    private void timer_Tick(object sender, EventArgs e)
    {
        UpdateElapsedTime();

       if (lblTime.InvokeRequired) 
       {
            lblTime.Invoke(new MethodInvoker(() => 
            { 
                lblTime.Text = sw.ElapsedTime;
            }));
       }
    }
}

Then, you can update your CStopWatch class to have include an UpdateElapsedTime method.

public class CStopWatch
{
    private Stopwatch sw = new Stopwatch();
    private DateTime startTime;
    private DateTime stopTime;
    private String elapsedTime;

    public String ElapsedTime
    {
        get
        { 
            return elapsedTime; 
        }
    }

    public String StartClock()
    {
        sw.Start();

        UpdateElapsedTime();

        return ElapsedTime;
    }

    public void UpdateElapsedTime()
    {
        TimeSpan ts = sw.Elapsed;
        ElapsedTime = String.Format("{0:00}:{1:00}:{2:00}", ts.Hours, ts.Minutes, ts.Seconds / 10); 
    }

    public void StopClock()
    {
        sw.Stop();
    }
}

Upvotes: 1

bottaio
bottaio

Reputation: 5093

The problem is that you actually don't update your elapsedTime variable. You can instead use your Stopwatch in ElapsedTime property:

public String ElapsedTime
{
    get
    {
        return string.Format("{0:00}:{1:00}:{2:00}", sw.Elapsed.Hours, sw.Elapsed.Minutes, sw.Elapsed.Seconds / 10);
    }
}

or equivalently (C# 6.0):

public String ElapsedTime => $"{sw.Elapsed.Hours:00}:{sw.Elapsed.Minutes:00}:{sw.Elapsed.Seconds/10:00}";

Upvotes: 0

Larry
Larry

Reputation: 18051

This is because elapsedTime is set once, then never updated.

public String ElapsedTime
{
    get
    { 
      return String.Format("{0:00}:{1:00}:{2:00}", sw.Elapsed);
    }
}

This should fix it. So elapsedTime declaration and initialization are not useful and can be removed:

public class CStopWatch
{
    Stopwatch sw = new Stopwatch();

    public String ElapsedTime
    {
        get
        { 
            return String.Format("{0:00}:{1:00}:{2:00}", sw.Elapsed);
        }            
    }

    public void StartClock()
    {
        sw.Start();
    }

    public void StopClock()
    {
        sw.Stop();
    }
}

Upvotes: 1

Eminem
Eminem

Reputation: 7484

try the following

timer.Elapsed += OnTimedEvent;
timer.Interval = 1000;
timer.Enabled = true;
sw.StartClock();

Add the following method:

private static void OnTimedEvent(Object source, ElapsedEventArgs e)
    {
        lblTime.Text = string.Format("{0:HH:mm:ss.fff}",e.SignalTime);
    }

Upvotes: 0

Valker
Valker

Reputation: 58

You assign value of variable elapsedTime only once after clicking on Start button. Later on you try to read value from it (using ElapsedTime property) in timer_Tick method however you do not assign new value. Try something like this:

public String ElapsedTime
    {
        get
        { 
            TimeSpan ts = sw.Elapsed;
            return String.Format("{0:00}:{1:00}:{2:00}",
        ts.Hours, ts.Minutes, ts.Seconds / 10);
        }
    }

Upvotes: 3

Chen Kinnrot
Chen Kinnrot

Reputation: 21015

check out this , I think the timer tick event occurs on another thread, that not allowed to update the ui, the link shows solutions depends on which .net version you are using.

Upvotes: 0

Related Questions