2013-04-26 2 views
2

У меня есть три DateTimePicker, где один из них является интервалом между начальным и конечным. В части кода я обновляю startdate.Value и enddate.Value, обновление ValueChanged событий interval.Value.Как предотвратить ошибку StackOverflow при изменении значений двух зависимых DateTimePickers?

DateTimePickers

Все отлично работает, когда значение в interval не нужно менять вручную. Но когда мне нужно изменить его вручную, это вызывает исключение StackOverflow, потому что когда установлено final.Value, это вызывает событие интервала ValueChanged, которое вызывает триггер, который меняет final.Value и т. Д.

Этот обработчик ValueChanged для startdate и enddate:

private void dates_ValueChanged(object sender, EventArgs e) 
    { 
     if (startdate.Value < enddate.Value) 
     { 
      TimeSpan diff = enddate.Value - startdate.Value; 
      DateTime newInterval = new DateTime(startdate.Value.Year, startdate.Value.Month, startdate.Value.Day, diff.Hours, diff.Minutes, diff.Seconds); 
      if (interval.Value != newInterval) 
       interval.Value = newInterval; 
     } 
    } 

И это обработчик ValueChanged для interval, который вызывает StackOverflow исключение:

private void interval_ValueChanged(object sender, EventArgs e) 
    { 
     int seconds = intervaloDP.Value.Hour * 3600 + intervaloDP.Value.Minute * 60 + intervaloDP.Value.Second; 
     finalDP.Value = finalDP.Value.AddSeconds(seconds); 
    } 

Есть ли способ изменить этот код и заставить его работать так, как мне нужно, чтобы он работал?

+1

'finalDP.Value = finalDP.Value.AddSeconds (в ​​секундах); 'кажется неправильным – leonbloy

ответ

3

Убедитесь, что всегда есть условие выхода:

var dtm = startDP.Value.AddSeconds(seconds); 
if (dtm != finalDP.Value) 
    finalDP.Value = dtm; 

Таким образом, это событие не срабатывает, если нет никаких изменений, чтобы сделать.

ОБНОВЛЕНИЕ: Изменен код, чтобы секунды были добавлены в startDP, а не finalDP.

+2

Хороший подход, но я боюсь, что исходный код кажется неправильным, секунды должны быть добавлены в startDp, а не в finalDP – leonbloy

+0

@leonbloy Top spot. :) Обновленный мой ответ, чтобы отразить это. – Jonathan

0

На самом деле, вы уже делаете правильно, обновляя интервал только при необходимости:

if (interval.Value != newInterval) interval.Value = newInterval; 

Это должно быть достаточно, чтобы избежать бесконечного цикла обновлений. Но вы вычисление неправильно другое обновления:

private void interval_ValueChanged(object sender, EventArgs e) 
    { 
     int seconds = intervaloDP.Value.Hour * 3600 + intervaloDP.Value.Minute * 60 + intervaloDP.Value.Second; 
     // finalDP.Value = finalDP.Value.AddSeconds(seconds); //wrong 
     finalDP.Value = startDP.Value.AddSeconds(seconds); 
    } 

(Кстати, вы должны определить ваше желаемое поведение, когда интервал пересекают 24:00:00 точку)

Смежные вопросы