如果用户在DateTimePicker日历中单击日期,如何识别

时间:2014-05-18 21:22:45

标签: vb.net winforms datepicker datetimepicker

我不希望用户在没有点击日期的情况下点击日历时更改日期。问题是当datepickercalendar打开时总是选择一个日期。我在Calender控件中寻找类似于DateSelected事件的东西

我有一个派生自DateTimePicker的类,它使用带有spacechar字符串的自定义格式,以便为DateTimePicker提供空字段。

我发现stackoverflow中有一篇文章有​​同样的问题,但解决方案不起作用。我没有足够的积分来发表评论(现在无法找到链接:()

就代码而言,这就是我所拥有的

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

4 个答案:

答案 0 :(得分:2)

CodeProject上至少有一个DateTimePicker控件允许可以为空的日期。但是有一种比这更简单的方法。

在设计中,将ShowCheckBox设置为True。然后,当表单加载或您要重置字段时,将Checked设置为False。这使得DTP看起来被禁用,这有点不幸,但是当用户打开DTP时,会自动检查复选框。因此,您需要做的就是评估他们是否选择了日期,即评估Checked属性。如果在选择有效日期后取消选中它们,则禁用的外观最终表示该值并未真正计算。

如果您使用较小的版本(ShowUpDown),则控件 将被禁用,直到他们首次单击该复选框,然后选择要旋转的字段。对于每个字段的每次更改,您仍会获得值更改事件,但这就是它应该如何工作。控件始终具有有效的日期值,因此您无需检查Nothing等。

答案 1 :(得分:0)

确保选择日期的另一种方法是“镜像”代码中的DTP值(这可能是您最终在子类控件中执行的操作)。这只是一个部分解决方案,因为如果控件翻转几个月,控件将设置一个日期值。它只是控制的工作方式。

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

它比ShowCheckbox方法多一些代码,但类似于子类化所需的代码。如果您对DTP进行子类化,则当镜像变量&lt;&gt;时,您可能会从此ValueChanged事件中引发一个新事件。 <{1}}和CheckDates不需要。

答案 2 :(得分:0)

一个老线程,但也许有人觉得这很有用......如果你正在寻找打开“空白”并仅选择日期的DTP如果用户选择它,那么这是(在我看来)最好也是最简单的选项:< / p>

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

这样打开时DTP为“空白”,并显示日期如果选择了一些。您还可以使用“退格”或“删除”键删除日期,甚至可以选择与之前相同的日期,这使得DTP类似于组合框/文本框的行为。与textbox / combobox相同的“退格”行为也可以通过更多编码(使用另一个文本框手动输入日期)来实现,但在我看来这已经足够了。干杯

答案 3 :(得分:0)

Private Sub DateTimePicker1_ValueChanged(ByVal sender As Object, ByVal e As EventArgs) Handles DateTimePicker1.ValueChanged
    Label42.Text = String.Format("{0:dd-MMM-yyyy HH:mm:ss}", DateTimePicker1.Value)
End Sub

Private Sub DateTimePicker1_DropDown(ByVal sender As Object, ByVal e As EventArgs) Handles DateTimePicker1.DropDown
    RemoveHandler DateTimePicker1.ValueChanged, AddressOf DateTimePicker1_ValueChanged
End Sub

Private Sub DateTimePicker1_CloseUp(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DateTimePicker1.CloseUp
    AddHandler DateTimePicker1.ValueChanged, AddressOf DateTimePicker1_ValueChanged
    Call DateTimePicker1_ValueChanged(sender, EventArgs.Empty)
End Sub