首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >停止时钟在wp7中的实现

停止时钟在wp7中的实现
EN

Stack Overflow用户
提问于 2011-12-31 19:54:18
回答 2查看 450关注 0票数 1

在我的wp7.5应用程序中,我有一个需要显示停止时钟的块(比如30,29,28...1,0)。我尝试了使用DispatchTimer和Timer类的各种实现来实现这一点,但是它们都没有解决我的问题。

方法1:这是我在DispatchTimer中使用的代码片段

代码语言:javascript
复制
DispatcherTimer dt = new DispatcherTimer();
dt.Interval = new TimeSpan(0, 0, 1); // 1 second
dt.Tick += new EventHandler(dt_Tick);

for(int count=0;count<30;count++)
    dt.Start();

void dt_Tick(object sender, EventArgs e)
{
   // my UI control update here
}

在我的Tick事件实现中,我正在使用time counter更新一个UI控件。我在这里读到了一些关于同一主题的问题,在某些情况下,由于UI线程,dispatcher tick永远不会触发。同样的事情也发生在我身上,tick事件从未触发过。

方法2:我尝试使用System.Threading.Timer类,

代码语言:javascript
复制
Timer timer = new Timer(TimerProc);

for(int count=0;count<30;count++)
    timer.Change(1000, 0);

void TimerProc(object sender)
{
   // my UI control update here
}

我的方法都没有奏效。我可能问了一个重复的问题,有人能指出我在代码中做错了什么吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-12-31 20:11:42

调用keep的Start()方法之后的DispatcherTimer会在间隔过后触发Tick event,直到您对其调用Stop()。所以您不需要调用Start() 30次,但是您必须维护一个计数器,并且在Tick event处理程序中,在30次滴答之后停止计时器:

代码语言:javascript
复制
private int counter;

private void Start_Click(object sender, RoutedEventArgs e)
{
    counter = 30;
    DispatcherTimer dt = new DispatcherTimer();
    dt.Interval = new TimeSpan(0, 0, 1); // 1 second
    dt.Tick += new EventHandler(dt_Tick);
    dt.Start();
}

void dt_Tick(object sender, EventArgs e)
{
    if (counter >= 0)
    {
        timeText.Text = counter.ToString();
        counter--;
    }
    else
        ((DispatcherTimer)sender).Stop();
}

编辑:

如果DispatcherTimer的精度不够,您可以改用System.Threading.Timer,但在这种情况下,您需要在tick事件处理程序中调用Dispatcher.BeginInvoke来启用对UI线程上的对象的访问:

代码语言:javascript
复制
private int counter;

private void Start_Click(object sender, RoutedEventArgs e)
{
    counter = 30;
    timeText.Text = counter.ToString();
    Timer dt = new Timer(dt_Tick);
    dt.Change(1000 /* delay to start the timer */, 1000 /* period time */);
}

private void dt_Tick(object sender)
{
    if (counter > 0)
    {
        Dispatcher.BeginInvoke(() => timeText.Text = counter.ToString());
        counter--;
    }
    else
        ((Timer) sender).Dispose();
}
票数 2
EN

Stack Overflow用户

发布于 2011-12-31 21:28:21

Timer tick方法不能是记录时间的方法。为什么?有两个原因。

1/ DispatcherTimer的每个刻度之间的间隔并不精确,这取决于您如何处理UI。它可以是1秒,也可以更长一点。

2/下一次滴答在前一次滴答结束一秒后触发。由于tick内的更新代码需要一些时间,因此它将自动落后。例如,如果更新代码需要0.1秒,那么在1秒后触发滴答,更新完成,下一个滴答出现在更新结束后1秒,所以计时器开始后2.1秒!

因此,您应该存储启动计时器的时间,并计算每个节拍的运行时间:

代码语言:javascript
复制
    protected DispatcherTimer Timer { get; set; }

    protected DateTime TimerStartTime { get; set; }

    private void ButtonStart_Click(object sender, RoutedEventArgs e)
    {
        this.Timer = new DispatcherTimer();
        this.Timer.Interval = TimeSpan.FromSeconds(1);
        this.Timer.Tick += this.Timer_Tick;
        this.TimerStartTime = DateTime.Now;
        this.Timer.Start();
    }

    private void Timer_Tick(object sender, EventArgs e)
    {
        int elapsedSeconds = (int)DateTime.Now.Subtract(this.TimerStartTime).TotalSeconds;

        this.TextTimer.Text = (30 - elapsedSeconds).ToString();
    }

这样,即使每个滴答之间的时间不精确,计时器也不会指示错误的时间。您甚至可以将计时器间隔减少到500毫秒或更短,以获得更精确的计时器,而无需更改计时方法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8687951

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档