How to contol the time interval in a DateTimePicker

前端 未结 6 1727
梦毁少年i
梦毁少年i 2020-12-20 19:33

I have a DateTimePicker control on a form specified like so:

dtpEntry.Format = DateTimePickerFormat.Custom;
dtpEntry.CustomFormat = \"dd/MM/         


        
相关标签:
6条回答
  • 2020-12-20 19:38

    It's possible by watching the ValueChanged event and override the value. This sample form worked well:

    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;
        }
    }
    
    0 讨论(0)
  • 2020-12-20 19:43

    I know this is an old article, but I created a better solution to this problem based on the answer above.

    in the class

    private DateTime prevTimePicker1;
    private bool navigatingDateTimePicker = false;
    

    in the constructor

    prevTimePicker1 = dateTimePickerStart.Value;
    navigatingDateTimePicker = false;
    

    the event

    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;
    }
    
    0 讨论(0)
  • 2020-12-20 19:48

    I've changed a little the answer from SixOThree, to eliminate the bug found by Necromporph. It should be ok like this:

    in the class

    private DateTime prevTimePicker1;
    private bool navigatingDateTimePicker = false;
    

    in the constructor

    prevTimePicker1 = dateTimePickerStart.Value;
    navigatingDateTimePicker = false;
    

    the event

    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;
    }
    
    0 讨论(0)
  • 2020-12-20 19:48

    Or simply try this:

    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);
    }
    
    0 讨论(0)
  • 2020-12-20 19:49

    The problem is that the up/down control automatically increments or decrements the currently highlighted portion of the date/time picker (i.e. year/month/day/hour/etc.).

    You are probably better off adding your own up/down control (perhaps a very small vscrollbar) immediately adjacent to the date/time picker and wiring it up to increment/decrement five minute intervals from the date/time picker's value.

    0 讨论(0)
  • 2020-12-20 19:50

    you could add this code

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

    before

    TimeSpan tempTS = dtpJamAppointmentDokter.Value - dtpJamAppointmentDokter.Value.Date;
    
    0 讨论(0)
提交回复
热议问题