how to identity if user clicked on a date in DateT

2019-01-28 22:53发布

I don't want the date to change when user clicks out of the calender without clicking on a date. The problem is One Date is always selected when the datepickercalendar opens up. I am looking for something similar to DateSelected event in the Calender control

I have a class that derives from DateTimePicker which uses custom format with a spacechar string for to have empty field for DateTimePicker.

I found an article in stackoverflow with same issue but the solution doesnot work. I don't have enough points to place comments either (unable to find the link now :( )

As far as code this is what i have

Public Class CustomDP
    Inherits System.Windows.Forms.DateTimePicker

    Public Sub New()
        CustomFormat = " "
        Format = System.Windows.Forms.DateTimePickerFormat.Custom
    End Sub

    Protected Overrides Sub OnValueChanged(eventargs As System.EventArgs)
        MyBase.OnValueChanged(eventargs)
    End Sub

    Protected Overrides Sub OnCloseUp(eventargs As System.EventArgs)
        Format = DateTimePickerFormat.Short
        MyBase.OnCloseUp(eventargs)
    End Sub

    Protected Overrides Sub OnDropDown(eventargs As System.EventArgs)
        Format = DateTimePickerFormat.Custom
        MyBase.OnDropDown(eventargs)
    End Sub
End Class

3条回答
倾城 Initia
2楼-- · 2019-01-28 23:26

There is already at least 1 DateTimePicker control on CodeProject which allows for a Nullable Date. But there is a simpler method than that.

In design, set the ShowCheckBox to True. Then when the form loads or you are resetting fields, set Checked to False. This makes the DTP look disabled which is a little unfortunate, but when the user opens the DTP, the Checkbox is automatically checked. So, all you need to do to see if they picked a date, is to evaluate the Checked property. The disabled appearance ends up indicating that the value doesnt really count, if they should happen to uncheck it after selecting a valid date.

If you use the smaller version (ShowUpDown), the control is disabled until they first click the checkbox, then select a field to spin thru. You will still get a value changed event for each change of each field, but thats how it is supposed to work. The control always has a valid date value so you dont have to check against Nothing etc.

查看更多
聊天终结者
3楼-- · 2019-01-28 23:31

An old thread but maybe someone finds this useful... If you're looking for DTP that opens "blank" and selects date only If user selects It, then this is (in my opinion) best and simplest option:

Private Sub Form_Load(sender As Object, e As EventArgs) Handles Form.Load

        DTP_Example.Format = DateTimePickerFormat.Custom
        DTP_Example.CustomFormat = " "

End Sub

 Private Sub DTP_Example_ValueChanged(sender As Object, e As EventArgs) Handles DTP_Example.ValueChanged

        DTP_Example.Format = DateTimePickerFormat.Long

 End Sub

 Private Sub DTP_Example_KeyDown(sender As Object, e As KeyEventArgs) Handles DTP_Example.KeyDown

        If e.KeyCode = Keys.Delete Or e.KeyCode = Keys.Back Then
            DTP_Example.Value = Now
            DTP_Example.Format = DateTimePickerFormat.Custom
            DTP_Example.CustomFormat = " "

        End If

    End Sub

This way you have DTP "blank" on open, and displays date If you select some. Also you can delete dates with "Backspace" or "Delete" keys and even select same date as before, which makes DTP simmilar behavior like combobox/textbox. Same "Backspace" behavior as in textbox/combobox can be achieved too, with a little more coding (using another Textbox to manually enter Dates), but in my opinion this is good enough. Cheers

查看更多
一夜七次
4楼-- · 2019-01-28 23:42

Another way to be sure a date is picked is to "mirror" the DTP value in code (which is likely what you'd end up doing in a subclassed control). This is only a partial solution because the control will set a date value if they flip thru months. Its just how the control works.

Public Class Form1

    ' "mirror" dtp value vars
    Private myFromDate As Date = Date.MinValue
    Private myToDate As Date = Date.MaxValue

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load

        ResetDates()

    End Sub

    Private Sub ResetDates()
        ' reset the dates for repeated entries,
        ' ValueChanged event will fire
        myFromDate = Date.MinValue
        myToDate = Date.MaxValue

        ' the button only enables for valid dates
        Button1.Enabled = False
    End Sub

    Private Sub CheckDates()

        ' signal that all is well
        Button1.Enabled = ((myFromDate <> Date.MinValue) AndAlso
                          (myToDate <> Date.MaxValue) AndAlso
                          (myToDate > myFromDate))

        ' debugging while a DTP is open can be...problematic
        Console.WriteLine("from {0} to {1}  {2}", 
                       myFromDate.ToString, myToDate.ToString, 
                       (myToDate > myFromDate).ToString)

    End Sub

    Private Sub dtp_ValueChanged(sender As Object, e As EventArgs) _
                        Handles dtpFrom.ValueChanged, dtpTo.ValueChanged

        Dim dtp As DateTimePicker = CType(sender, DateTimePicker)

        Select Case dtp.Name
            Case "dtpFrom"
                If dtp.Value = dtp.MinDate Then
                    myFromDate = Date.MinValue      ' used when Resetting
                Else
                    ' myFromDate <> Date.Min acts as a flag
                    myFromDate = dtp.Value          
                End If

            Case "dtpTo"
                If dtp.Value = dtp.MaxDate Then
                    myToDate = Date.MinValue        ' Resetting
                Else
                    myToDate = dtp.Value            ' user pick
                End If
        End Select

        CheckDates()
    End Sub

Its a bit more code than the ShowCheckbox method but something like what you would need for subclassing. If you subclass the DTP, you'd likely raise a new event from this ValueChanged event when the mirror variable <> Date.Min|Max and CheckDates would not be needed.

查看更多
登录 后发表回答