2010-12-02 68 views
2

我想要一个计数器从60秒倒计时到0.我希望用户看到用户界面上的秒数。要做到这一点,我想我会显示一个像这样的基本TextBlock:在Silverlight中创建一个倒数计时器

<StackPanel> 
    <TextBlock Text=" " /> 
    <TextBlock Text=" seconds remaining" /> 
</StackPanel> 

然后,我想使用一个计时器。我知道的唯一计时器是DispatcherTimer。但是,这并不显示已经过了多长时间或剩余多少时间。正因为如此,我没有任何约束力。

private DispatcherTimer myTimer = new DispatcherTimer();  
public MainPage() { 
    myTimer.Interval = new TimeSpan(0, 0, 60); 
    myTimer.Tick += new EventHandler(myTimer_Tick); 
    myTimer.Start(); 
} 

我不知道该怎么做。一位同事告诉我,我甚至不应该这样做,因为它会减慢用户界面。但用户真的很想要它。有人可以告诉我:

1)它会真的让用户界面变得非常糟糕吗? 2)如果不是,我该怎么做?

谢谢!

回答

3
  1. 是的。它会以不可思议的量减缓它。坦率地说,担心这件事绝对荒谬。

  2. 在每个滴答声上,递减一个属性。将您的用户界面绑定到该属性。或者,只需使每个滴答的属性无效,并让属性getter计算剩余时间。

选项1

myTimer.Interval = TimeSpan.FromSeconds(1); 
myTimer.Tick += delegate 
{ 
    this.SecondsRemaining = this.SecondsRemaining - 1; 

    if (this.SecondsRemaining == 0) 
    { 
     myTimer.Dispose(); 
    } 
}; 
this.SecondsRemaining = 60; 
myTimer.Start(); 

... 

// assumes your class implements INotifyPropertyChanged and you have a helper method to raise OnPropertyChanged 
public int SecondsRemaining 
{ 
    get { return this.secondsRemaining; } 
    private set 
    { 
     this.secondsRemaining = value; 
     this.OnPropertyChanged(() => this.SecondsRemaining); 
    } 
} 

选项2

myTimer.Interval = TimeSpan.FromSeconds(1); 
myTimer.Tick += delegate 
{ 
    this.OnPropertyChanged("TimeRemaining"); 

    if (this.TimeRemaining <= 0) 
    { 
     myTimer.Dispose(); 
    } 
}; 
this.endTime = DateTime.UtcNow.AddMinutes(1); 
myTimer.Start(); 

public int TimeRemaining 
{ 
    get { return (endTime - DateTime.UtcNow).TotalSeconds; } 
} 
1

不,它不应该陷入困境的UI下来,因为它会被解雇每秒;关于如何做到这一点的样本可以找到here

此外,您还可以使用一个Storyboard,它可以在您指定的时间范围内运行并相应地调整UI组件,但我不会推荐这种方法。