0

我正在为我正在从事的项目实施计时器。每当按下按钮时都会触发计时器。

第一次按下时,它会设置定时器的持续时间,然后启动定时器。每当计时器滴答时,程序就会减少持续时间并将其打印到屏幕上。它工作得很好......直到你在计时器运行时再次按下按钮。当您执行此操作时,tick 事件中的操作会发生您在按钮运行时按下按钮的次数。

我的 XAML 看起来像这样。

<Grid Grid.Row="1">
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <TextBlock x:Name="tBox" Text="TIMER" Grid.Row="0" HorizontalAlignment="Center" Style="{StaticResource PhoneTextTitle2Style}"/>
    <TextBlock x:Name="timer" Text="00"  Grid.Row="1" HorizontalAlignment="Center" Style="{StaticResource PhoneTextTitle1Style}"/>
</Grid>

<Button 
    Grid.Row="1" 
    Grid.Column="0"
    Content="Online" 
    HorizontalAlignment="Center"
    Width="200"
    Height="75" Click="trigger" />

我的 C# 看起来像这样:

public partial class MainPage : PhoneApplicationPage
{
    int duration = 0;
    int converted = 0;
    int count = 0;
    DispatcherTimer tmr = new DispatcherTimer();

    // Constructor
    public MainPage()
    {
        InitializeComponent();
    }

    private void trigger(object sender, RoutedEventArgs e)
    {
        resetTimer();
        timer.Text = "30";
        tmr.Interval = TimeSpan.FromSeconds(1);
        tmr.Tick += OnTimerTick;
            tmr.Start();
    }

    void OnTimerTick(object sender, EventArgs args)
    {
        converted = duration - 1;
        timer.Text = converted.ToString();
        duration = converted;
        tBox.Text = strConvert;
        count = count + 1;
        if (duration == 0)
        {
            tmr.Stop();
        }
    }

    void resetTimer()
    {
        count = 0;
        DispatcherTimer tmr = new DispatcherTimer();
        tmr.Interval = TimeSpan.FromSeconds(0);
        duration = 30;
        converted = 0;
        tmr.Stop();
    }
}
4

3 回答 3

2

不要Tick在方法中为事件添加处理程序。添加Tick事件处理程序,设置间隔,并在创建窗口时(即在构造函数中)创建一次计时器,然后在按下按钮时仅创建Start计时器。

按下按钮时也不应创建新计时器;您可以并且应该重新使用现有的计时器。

您实际上并没有多次触发计时器。Tick发生的情况是,每次按下按钮时,您都向事件添加了相同的方法作为处理程序,因此您的方法被多次调用时Tick事件触发时。调用已经运行的计时器不会导致它多次触发,它只会重置它的间隔(我认为这是需要的)。Start

于 2013-01-07T19:08:05.280 回答
0

重写 reset 方法以在关闭现有计时器之前不创建新的计时器引用。

void resetTimer()
{
    count = 0;
    tmr.Stop();
    tmr.Interval = TimeSpan.FromSeconds(0);
    duration = 30;
    converted = 0;
}

同样,在页面加载时设置 Tick 事件处理程序

// Constructor
public MainPage()
{
    InitializeComponent();
    timer.Text = "30";
    tmr.Interval = TimeSpan.FromSeconds(1);
    tmr.Tick += OnTimerTick;
}

private void trigger(object sender, RoutedEventArgs e)
{
        resetTimer();
        tmr.Start();
}

更是如此,

您应该在 tick 方法执行时停止计时器,除非您可以在 tick 方法需要一段时间执行时多次运行它

    void OnTimerTick(object sender, EventArgs args)
    {
tmr.Stop();        
converted = duration - 1;
        timer.Text = converted.ToString();
        duration = converted;
        tBox.Text = strConvert;
        count = count + 1;
tmr.Start();
    }
于 2013-01-07T19:09:22.507 回答
0

问题是每次调用 trigger() 时,您都在添加 OnTimerTick 处理程序方法的新实例,我从它的签名中假设是每当用户单击按钮时。

我会做两件事之一;要么删除/禁用 trigger() 方法主体中的按钮,因此用户不能多次单击它,要么在附加对 OnTimerTick 的引用之前检查 Tick 事件以确保它为空(没有处理程序)。

于 2013-01-07T19:09:32.243 回答