Как контролировать временной интервал в DateTimePicker - PullRequest
4 голосов
/ 04 декабря 2009

У меня есть DateTimePicker элемент управления в форме, указанной так:

dtpEntry.Format = DateTimePickerFormat.Custom;
dtpEntry.CustomFormat = "dd/MM/yyyy hh:mm:ss";
dtpEntry.ShowUpDown = true;

Я бы хотел, чтобы пользователь мог увеличивать или уменьшать время только на 5 минут.

Какие-нибудь предложения о том, как этого добиться?

Ответы [ 6 ]

7 голосов
/ 04 декабря 2009

Это возможно, наблюдая за событием ValueChanged и переопределяя значение. Этот образец формы работал хорошо:

public partial class Form1 : Form {
    public Form1() {
        InitializeComponent();
        dateTimePicker1.CustomFormat = "dd/MM/yyyy hh:mm";
        dateTimePicker1.Format = DateTimePickerFormat.Custom;
        dateTimePicker1.ShowUpDown = true;
        dateTimePicker1.Value = DateTime.Now.Date.AddHours(DateTime.Now.Hour);
        mPrevDate = dateTimePicker1.Value;
        dateTimePicker1.ValueChanged += new EventHandler(dateTimePicker1_ValueChanged);
    }
    private DateTime mPrevDate;
    private bool mBusy;

    private void dateTimePicker1_ValueChanged(object sender, EventArgs e) {
        if (!mBusy) {
            mBusy = true;
            DateTime dt = dateTimePicker1.Value;
            if ((dt.Minute * 60 + dt.Second) % 300 != 0) {
                TimeSpan diff = dt - mPrevDate;
                if (diff.Ticks < 0) dateTimePicker1.Value = mPrevDate.AddMinutes(-5);
                else dateTimePicker1.Value = mPrevDate.AddMinutes(5);
            }
            mBusy = false;
        }
        mPrevDate = dateTimePicker1.Value;
    }
}
5 голосов
/ 31 октября 2012

Я немного изменил ответ от SixOThree, чтобы устранить ошибку, обнаруженную Некромпорфом. Это должно быть хорошо, как это:

в классе

private DateTime prevTimePicker1;
private bool navigatingDateTimePicker = false;

в конструкторе

prevTimePicker1 = dateTimePickerStart.Value;
navigatingDateTimePicker = false;

событие

private void dateTimePickerStart_ValueChanged(object sender, EventArgs e)
{
  if (!navigatingDateTimePicker) {
    /* First set the navigating flag to true so this method doesn't get called again while updating */
    navigatingDateTimePicker = true;

    /* using timespan because that's the only way I know how to round times well */
    TimeSpan tempTS = dateTimePickerStart.Value - dateTimePickerStart.Value.Date;
    TimeSpan roundedTimeSpan;

    TimeSpan TDBug = dateTimePickerStart.Value - prevTimePicker1;
    if (TDBug.TotalMinutes == 59)
    {
        // first: if we are going back and skipping an hour it needs an adjustment
        roundedTimeSpan = TimeSpan.FromMinutes(5 * Math.Floor((tempTS.TotalMinutes - 60) / 5));
        dateTimePickerStart.Value = dateTimePickerStart.Value.Date + roundedTimeSpan;
    }
    else if (dateTimePickerStart.Value > prevTimePicker1)
    {
        // round up to the nearest interval
        roundedTimeSpan = TimeSpan.FromMinutes(5 * Math.Ceiling(tempTS.TotalMinutes / 5));
        dateTimePickerStart.Value = dateTimePickerStart.Value.Date + roundedTimeSpan;
    } else {
        // round down to the nearest interval from prev
        roundedTimeSpan = TimeSpan.FromMinutes(5 * Math.Floor(tempTS.TotalMinutes / 5));
        dateTimePickerStart.Value = dateTimePickerStart.Value.Date + roundedTimeSpan;
    }
    navigatingDateTimePicker = false;
  }
  prevTimePicker1 = dateTimePickerStart.Value;
}
1 голос
/ 19 апреля 2016

Или просто попробуйте это:

private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
{
    if (this.dateTimePicker1.Value.Minute % 5 == 0)
        return;

    if (this.dateTimePicker1.Value.Minute % 5 == 1)
        this.dateTimePicker1.Value = this.dateTimePicker1.Value.AddMinutes(4);

    if (this.dateTimePicker1.Value.Minute % 5 == 4)
        this.dateTimePicker1.Value = this.dateTimePicker1.Value.AddMinutes(-4);
}
1 голос
/ 04 декабря 2009

Проблема заключается в том, что элемент управления вверх / вниз автоматически увеличивает или уменьшает текущую выделенную часть средства выбора даты / времени (то есть год / месяц / день / час / и т. Д.).

Возможно, вам лучше добавить свой собственный элемент управления вверх / вниз (возможно, очень маленькую полосу прокрутки), непосредственно примыкающий к датчику / времени, и подключать его с шагом / уменьшением пятиминутных интервалов от значения средства выбора даты / времени.

0 голосов
/ 28 сентября 2011

Вы можете добавить этот код

int minuteDiff = dtpJamAppointmentDokter.Value.Minute - prevTimePicker1.Minute;

if (minuteDiff == 59)
{
    dtpJamAppointmentDokter.Value =  dtpJamAppointmentDokter.Value.AddHours(-1);
}

до

TimeSpan tempTS = dtpJamAppointmentDokter.Value - dtpJamAppointmentDokter.Value.Date;
0 голосов
/ 03 августа 2011

Я знаю, что это старая статья, но я создал лучшее решение этой проблемы, основываясь на ответе выше.

в классе

private DateTime prevTimePicker1;
private bool navigatingDateTimePicker = false;

в конструкторе

prevTimePicker1 = dateTimePickerStart.Value;
navigatingDateTimePicker = false;

событие

private void dateTimePickerStart_ValueChanged(object sender, EventArgs e)
{
  if (!navigatingDateTimePicker) {
    /* First set the navigating flag to true so this method doesn't get called again while updating */
    navigatingDateTimePicker = true;

    /* using timespan because that's the only way I know how to round times well */
    TimeSpan tempTS = dateTimePickerStart.Value - dateTimePickerStart.Value.Date;
    TimeSpan roundedTimeSpan;

    if (dateTimePickerStart.Value > prevTimePicker1) {
      // round up to the nearest interval
      roundedTimeSpan = TimeSpan.FromMinutes(5 * Math.Ceiling(tempTS.TotalMinutes / 5));
      dateTimePickerStart.Value = dateTimePickerStart.Value.Date + roundedTimeSpan;
    } else {
      // round down to the nearest interval from prev
      roundedTimeSpan = TimeSpan.FromMinutes(5 * Math.Floor(tempTS.TotalMinutes / 5));
      dateTimePickerStart.Value = dateTimePickerStart.Value.Date + roundedTimeSpan;
    }
    navigatingDateTimePicker = false;
  }
  prevTimePicker1 = dateTimePickerStart.Value;
}
...