2016-11-07 98 views
2

我正在使用WinForm的。我的表单中有一个标签,应该从0:20秒开始倒数。到0:00秒。我试图在这里做,但编译器给我一个错误。时间跨度减秒表倒计时

Error: Cannot convert from 'int' to 'System.TimeSpan'

为什么不能使用timespan.Subtract()?我怎么能从0:20秒到0:00秒?

private void timer1_Tick(object sender, EventArgs e) 
    { 
     TimeSpan timespan = TimeSpan.FromSeconds(20); 

     Stopwatch stopwatch = new Stopwatch(); 
     stopwatch.Start(); 
     Time_label.Text = timespan.Subtract(stopwatch.Elapsed.Seconds); 
    } 
+2

请注意,'stopwatch.Elapsed.Seconds'只是秒*组件*,因此它从0到59计数,然后再次回滚到0。你可能想要'stopwatch.Elapsed.TotalSeconds'继续计数59.除非你正在做一个公鸡来展示,否则我发现很少有人真正需要'Seconds'而不是'TotalSeconds'。 – Quantic

+0

你不需要使用'StopWatch'。你只需要使用一个计时器,但是当你想启动计时器时,首先计算'EndTime'或'StopTime',然后启动计时器。在每个勾号中,您应该更新标签的文本,并检查您是否达到了结束时间,然后停止计时器并在标签上显示'00:00'。您可能会发现这篇文章有用:[显示时间已过](https://stackoverflow.com/questions/38420596/display-time-elapsed) - 我相信这是一个确切的副本。 –

+1

你的事件不需要使用'TimeSpan',看看链接的帖子,并设置结束时间'endTime = DateTime.Now.AddSeconds(20);' –

回答

3

一个简单的第二个计数器更好的方法是使用Timer本身。

private readonly Timer _timer;  
private TimeSpan _timespan; 
private readonly TimeSpan _oneSecond; 

public Form1() 
{ 
    InitializeComponent(); 

    _timer = new Timer(); 
    _timer.Tick += timer1_Tick; 
    _timer.Interval = 1000;  

    _timespan = TimeSpan.FromSeconds(20); 
    _oneSecond = new TimeSpan(0, 0, 0, 1); 

    _timer.Start(); 
} 

private void timer1_Tick(object sender, EventArgs eventArgs) 
{ 
    if (_timespan >= TimeSpan.Zero) 
    { 
     Time_label.Text = _timespan.ToString(@"m\:ss"); 
     _timespan = _timespan.Subtract(_oneSecond); 
    } 
    else 
    { 
     _timer.Stop(); 
    } 
} 
+0

我的标签不会倒计时/或更新,虽然它停留在00:00:19秒 – taji01

+0

如果它说“00:00:19”您的代码不会“正确复制”,因为我的示例会说“0:20 “(根据您的预期结果)开始时。 – Jim

2

stopwatch.Elapsed.Seconds回报和int,具体地,秒数。 timespan.Subtract(TimeSpan)接受TimeSpan对象。

你可以试试:

Time_label.Text = 20 - stopwatch.Elapsed.Seconds; 

Time_label.Text = timespan.Subtract(stopwatch.Elapsed).Seconds; 

请注意有你的逻辑缺陷。每当您触发滴答事件时,您都会重新启动一个新的秒表,因此每次触发时都会有一个新的0:00秒表,并且您将在文本框中显示19或20。 在其他地方实例化您的秒表,因此它在刻度之间是相同的。

编辑: 作为由Quantic的评论所说,如果你打算具有比秒

Time_label.Text = (int)timespan.Subtract(stopwatch.Elapsed).TotalSeconds; 
+0

Upvote为您的编辑添加其他实现。 stopwatch.Elapsed是一个时间跨度,它是时间跨度的参数。减少。不需要铸造。 – Botonomous

+1

'.TotalSeconds'更安全。 '。Seconds'只是“Seconds组件”,只在0到59之间。 – Quantic

+0

@Quantic Nice,TotalSeconds也是double,比int32更精确。 – Botonomous

1

TimeSpan.Subtract一分钟的价值更期望另一个时间跨度结构。 Stopwatch.Elapsed.Seconds是一个Int32结构。没有任何内置的转换将Int32转换为TimeSpan。你可以试试这个

Time_label.Text = timespan.Subtract(TimeSpan.FromSeconds(stopwatch.Elapsed.seconds)).ToString(); 
0

TimeSpan.Subtract期望你从中减去时间跨度的另一个实例(时间跨度本身不绑定到特定的时间单位,所以减去说“15”,它并不“知道“你想要什么单位)。

你想要的是要么

Time_label.Text = Timespan.Subtract(TimeSpan.FromSeconds(stopwatch.Elapsed.Seconds))); 

产生一个相当漂亮的预格式化

00:00:20 

或(服用的事实,秒表的经过的是一个时间跨度自身优势)

Time_label.Text = timespan.Subtract(stopwatch.Elapsed); 

但是,生产

00:00:19.9999765 

这可能太精确,无法显示给最终用户(这是由于秒表精确无误)。