Home > database >  Can I use "dials" to select date?
Can I use "dials" to select date?

Time:12-16

I'm creating a visual basic form which contains two date picker controls. I don't like the user having to scroll through calendars to find the correct date. On various sites where I've had to enter a date (usually a birth date), there will be 3 "dials", one each for month, day and year, and you scroll around each one and then select the date you want. Does anyone know if this can be set up in vb? I've searched the internet and also through documentation for date pickers but I couldn't find anything. I'd appreciate knowing if: a) this can be done in visual basic, and b) if so, where I could find instructions on how to do it.

CodePudding user response:

Not an exact solution but it works pretty closely. Instead of using a DatePicker control, I'm using three combo boxes - one each for month, day and year. These combo boxes are loaded when the form loads. Once the user has selected a proper value for each (some checking has to be done to eliminate such things as February 30th), I concatenate the values from the three boxes and convert to date format. This seems to work pretty well.

CodePudding user response:

Actual solution along the lines of your own answer:

Controls in designer:

DateTimePicker1 As DateTimePicker
YearComboBox As ComboBox
MonthComboBox As ComboBox
DayComboBox As ComboBox
Private earliestYear As Integer = 1900
Private latestYear As Integer = DateTime.Now.Year '   x ' if going x years into the future

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    setDataSources(DateTime.Today)
End Sub

Private Sub setDataSources(d As DateTime)
    RemoveHandler YearComboBox.SelectedValueChanged, AddressOf YearMonthComboBox_SelectedValueChanged
    RemoveHandler MonthComboBox.SelectedValueChanged, AddressOf YearMonthComboBox_SelectedValueChanged
    RemoveHandler DayComboBox.SelectedValueChanged, AddressOf DayComboBox_SelectedValueChanged
    Dim yearDataSource = Enumerable.
        Range(earliestYear, DateTime.Now.Year - earliestYear   1).
        OrderByDescending(Function(y) y).
        ToList()
    YearComboBox.DataSource = yearDataSource
    YearComboBox.SelectedItem = d.Year

    Dim monthDataSource = DateTimeFormatInfo.CurrentInfo.MonthNames.
        Where(Function(month) Not String.IsNullOrEmpty(month)).
        Select(Function(month, i) New KeyValuePair(Of Integer, String)(i   1, month)).
        ToList()
    MonthComboBox.DisplayMember = "Value"
    MonthComboBox.ValueMember = "Key"
    MonthComboBox.DataSource = monthDataSource
    MonthComboBox.SelectedValue = d.Month

    Dim dayDataSource = Enumerable.
        Range(1, DateTime.DaysInMonth(d.Year, d.Month)).
        ToList()
    DayComboBox.DataSource = dayDataSource
    DayComboBox.SelectedItem = d.Day
    AddHandler YearComboBox.SelectedValueChanged, AddressOf YearMonthComboBox_SelectedValueChanged
    AddHandler MonthComboBox.SelectedValueChanged, AddressOf YearMonthComboBox_SelectedValueChanged
    AddHandler DayComboBox.SelectedValueChanged, AddressOf DayComboBox_SelectedValueChanged
End Sub

Private Sub YearMonthComboBox_SelectedValueChanged(sender As Object, e As EventArgs)
    Dim daysInMonth = DateTime.DaysInMonth(CInt(YearComboBox.SelectedItem), CInt(MonthComboBox.SelectedValue))
    Dim selectedDay = CInt(DayComboBox.SelectedItem)
    Dim dayDataSource = Enumerable.Range(1, daysInMonth).ToList()
    DayComboBox.DataSource = dayDataSource
    DayComboBox.SelectedItem = Math.Min(daysInMonth, selectedDay)
    DateTimePicker1.Value = New DateTime(CInt(YearComboBox.SelectedItem), CInt(MonthComboBox.SelectedValue), CInt(DayComboBox.SelectedItem))
End Sub

Private Sub DayComboBox_SelectedValueChanged(sender As Object, e As EventArgs)
    DateTimePicker1.Value = New DateTime(CInt(YearComboBox.SelectedItem), CInt(MonthComboBox.SelectedValue), CInt(DayComboBox.SelectedItem))
End Sub

Private Sub DateTimePicker1_ValueChanged(sender As Object, e As EventArgs) Handles DateTimePicker1.ValueChanged
    setDataSources(DateTimePicker1.Value)
End Sub

Interaction with each control will update other controls accordingly, taking into account number of days per month and leap years.

  • Related