2014-12-08 3 views
1

저는 지난 며칠 동안이 작업에 어려움을 겪어 왔으며 모두 도와 주실 수 있기를 바랍니다. WPF 타이머 응용 프로그램을 만들고 DispatcherTimer를 사용하여 시간을 추적하는 데 수분 내에 위쪽으로 셀 수 있습니다. 타이머를 처음 시작할 때 완벽하게 작동합니다. 그러나 타이머를 멈추었을 때 다시 시작하면 2 초에 카운트되기 시작합니다. 다시 한 번 해보면 3 초가됩니다. DispatcherTimer로 할 수있는 일이 무엇인지에 대해서는 확신 할 수 없기 때문에 실제로 도움을받을 수 있습니다.WPF DispatcherTimer가 다시 시작될 때 간격을 건너 뜁니다.

시작 단추를 클릭 할 때 호출되는 초기 함수입니다.

private void TimerStart(object sender, RoutedEventArgs e) 
{ 
    if ((string) TimerBlock.Content == "--:--") 
    { 
     TimerBlock.Content = "00:00"; 
     TimerTray.Content = "00:00"; 
    } 
    else 
    { 
     var timerString = TimerBlock.Content.ToString(); 
     _minute = Convert.ToInt32(timerString.Substring(0, 2)); 
     _hour = Convert.ToInt32(timerString.Substring(3, 2)); 
    } 
    _timer.Interval = TimerBlock.Content.ToString(); 
    _timer.Tick += dispatcherTimer_tick; 
    _timer.Start(); 
    TaskBarStop.IsChecked = false; 
    TimerStatus.Content = "The Timer Has Started"; 
    TimerStatus.Foreground = System.Windows.Media.Brushes.DarkGreen; 
    TimerTrayStatus.Content = "STARTED"; 
    TimerTrayStatus.Foreground = System.Windows.Media.Brushes.DarkGreen; 
    StartButton.IsEnabled = false; 
    StopButton.IsEnabled = true; 
} 

여기에 체크 표시가 있습니다.

private void dispatcherTimer_tick(object sender, EventArgs e) 
{ 
    if (_minute++ == 60) 
    { 
     _minute = 0; 
     _hour++; 
    } 

    if (_hour < 10 && _minute < 10) 
     TimerBlock.Content = "0" + _hour + ":0" + _minute; 
    else if (_hour < 10 && _minute >= 10) 
     TimerBlock.Content = "0" + _hour + ":" + _minute; 
    else if (_hour >= 10 && _minute < 10) 
     TimerBlock.Content = _hour + ":0" + _minute; 
    else 
     TimerBlock.Content = _hour + ":" + _minute; 

    TimerTray.Content = TimerBlock.Content; 
    CommandManagaer.InvalidateRequerySuggested(); 
} 

그리고 여기는 정지 버튼을 누를 때 호출되는 메소드입니다. 그것이 내가 다른 곳에서 아주 나쁜 일을 엉망으로 한 경우 내가 내려다 보이는, 또는 해요 것을 단지 작은 뭔가 경우

private void TimerStop(object sender, RoutedEventArgs e) 
{ 
    _timer.Stop(); 
    TaskBarStart.IsChecked = false; 
    TimerStatus.Content = "The Timer Has Stopped"; 
    TimerStatus.Foreground = System.Windows.Media.Brushes.DarkRed; 
    TimerTrayStatus.Content = "STOPPED"; 
    TimerTrayStatus.Foreground = System.Windows.Media.Brushes.DarkRed; 
    StartButton.IsEnabled = true; 
    StopButton.IsEnabled = false; 

    using (var db = new TimerDb()) 
    {    
     var timer = TimerBlock.Content.ToString(); 
     var session = new TimerSession(); 

     if (db.TemporaryTimeActivities.Any()) 
      session.SetTimeActivity(timer);    
     else 
      session.UpdateTime(timer); 
    } 
} 

기본적으로, 나는 알아낼 수 없습니다. 어떤 도움이라도 대단히 감사하겠습니다. 다시 시작될 때마다 간격을 1 씩 늘리는 원인이되는 코드에 무엇이 있습니까?

답변

1

타이머를 시작할 때마다 틱 처리기를 한 번만 연결해야합니다.

그래서 TimerStart 방법에서 광고

_timer.Tick += dispatcherTimer_tick; 

이동하고 예 넣어 창 또는 UserControl의 생성자에서.

또한 타이머의 Interval이 올바르게 설정되어 있는지 확인해야합니다. 당신이 매 분마다 한 번라는 틱 핸들러를 얻고 싶은 것 같습니다, 그래서 당신은 적절하게 설정해야합니다 : 그것은 또한 쉽게 (더 정확한) 분을 직접 계산하지 않는 것

_timer.Interval = TimeSpan.FromMinutes(1.0); 

하지만, 대신 DateTimeTimeSpan 구조체를 사용하십시오. DateTime.Now 속성을 사용하여 TimerStart 메서드에서 DateTime 형식의 필드에 시작 시간을 저장합니다.

private DateTime started; 

private void TimerStart(object sender, RoutedEventArgs e) 
{ 
    ... 
    started = DateTime.Now; 
} 

와 타임 스팬 클래스의 문자열 서식 기능을 활용 :

private void dispatcherTimer_tick(object sender, EventArgs e) 
{ 
    var elapsedTime = DateTime.Now - started; 
    TimerBlock.Content = elapsedTime.ToString(@"hh\:mm"); 
    ... 
} 
+0

는 당신의 도움을 주셔서 감사합니다! 한 번만 Tick 처리기에 전화하는 걸 몰랐어. 그리고 DateTime 및 TimeSpan 구조체는이 모양을 훨씬 더 깔끔하게 만듭니다. 고맙습니다! – Atarinerd80