WinForm DateTimePicker蓝调。那是我吗?

时间:2010-12-10 15:12:10

标签: winforms datetimepicker

我希望能够使用DateTimePicker控件接受NULL日期。

“已检查”属性似乎用于指定控件是“保留日期”还是现在。但是,当“未选中”时,日期仍会显示,但它似乎已禁用。对我来说,这让人分心。如果未选中复选框的意图是指示没有日期值,为什么有任何日期值禁用或出现在文本框中?在我看来,如果未选中控件,则文本框应为EMPTY,并且当用户真正想要“无值”时会看到灰暗的日期值会分散注意力。

如果用户切换了复选框,那么我希望能够将默认值放入文本框中。

我正在考虑创建一个在dateTimePicker控件和textBox之间切换的usercontrol,但我不想经历这个麻烦。

我尝试查看Telerik的DateTimePicker,但试图从该控件中获得合适的空值处理功能似乎更糟。我希望看到一个工作示例,您认为其中一个是用户友好的代码示例,其中std MS或Telerik DateTimePicker控件接受空输入。

我查看了一些开源控件,但每次修复一个问题时,都会介绍其他问题。

编辑:

请参阅下面的答案。它似乎工作正常,现在我只想让它成为每个DateTimePicker行为的一部分。

4 个答案:

答案 0 :(得分:1)

我遇到了同样的问题。好吧,实际上我很聪明,但我的用户遇到了问题。

我通过删除复选框并添加2个单选按钮解决了问题。现在看起来像这样:

(使用伪UI)

O No value entered
O | 1/1/2010   |V|

当没有值(null)时检查顶部radiobutton,当有值时检查底部displaybutton。我没有隐藏或禁用底部控件,用户似乎也明白。

缺点是,它需要更多的空间。

PS:用户抱怨的下一件事就是在组合框有焦点时使用滚轮。

答案 1 :(得分:1)

Klugey,但似乎完成了工作。如果未选中该复选框,则假定为NULL值。

Private Sub DateTimePicker1_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DateTimePicker1.ValueChanged


    If DateTimePicker1.Checked Then
        DateTimePicker1.Format = DateTimePickerFormat.Short 'Or whatever the original format was
    Else
        DateTimePicker1.Format = DateTimePickerFormat.Custom
        DateTimePicker1.CustomFormat = " "
    End If

End Sub

好的,下一个问题......如何将此行为转换为子类DateTimePicker?我想要做的是捕获在属性窗口中设置的格式和CustomFormat属性的原始值。但是,这显然不是这样做的方式。

这是我的微弱尝试:

Public Class NullableDateTimePicker

    Inherits DateTimePicker

    Private _OriginalFormat As DateTimePickerFormat
    Private _OriginalCustomerFormat As String

    Private Sub NullableDateTimePicker_ValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.ValueChanged

        If Me.Checked Then
            Me.Format = _OriginalFormat
            Me.CustomFormat = _OriginalCustomerFormat
        Else
            Me.Format = DateTimePickerFormat.Custom
            Me.CustomFormat = " "
        End If
    End Sub

    Private Sub _DP_FormatChanged(ByVal sender As Object, ByVal e As System.EventArgs)

        Static Count As Integer

        If Count = 0 Then
            _OriginalFormat = Me.Format
            _OriginalCustomerFormat = Me.CustomFormat
        End If

        Count += 1

    End Sub

    Public Sub New()
        AddHandler MyBase.FormatChanged, AddressOf _DP_FormatChanged
    End Sub
End Class

答案 2 :(得分:1)

我意识到这是你的初步问题已经存在很多年了,但这里是Telerik RadDateTimePicker的一个子类,可以满足您的要求:

Imports Telerik.WinControls.UI

Public Class DateTimePickerWithNull
    Inherits Telerik.WinControls.UI.RadDateTimePicker

    Private ReadOnly _calendar As RadCalendar

    Sub New()
        Dim calendarBehavior As RadDateTimePickerCalendar = Me.DateTimePickerElement.GetCurrentBehavior()
        calendarBehavior.DropDownMinSize = New Size(220, 150)

        _calendar = calendarBehavior.Calendar
        _calendar.ShowFooter = True

        AddHandler _calendar.ClearButton.Click, AddressOf ClearButton_Click
        AddHandler _calendar.TodayButton.Click, AddressOf TodayButton_Click
    End Sub

    Private Sub ClearButton_Click(sender As Object, e As EventArgs)
        'Do this to put the calendar away
        _calendar.SelectedDate = _calendar.FocusedDate

        'Then clear
        Me.SetToNullValue()
    End Sub

    Private Sub TodayButton_Click(sender As Object, e As EventArgs)
        _calendar.SelectedDate = _calendar.FocusedDate
    End Sub

End Class

获取选择器的值:

If DateTimePicker1.Value.Date = DateTimePicker1.NullDate Then
    Label1.Text = "Null"
Else
    Label1.Text = DateTimePicker1.Value.ToLongDateString
End If

答案 3 :(得分:0)

要做对,有点棘手。这看起来不错:

Imports System.ComponentModel

Public Class MyDateTimePicker
    Inherits DateTimePicker
    Implements ISupportInitialize

    Public Sub New()
        Me.ShowCheckBox = True
        Me.NullDate = True
    End Sub

    Private CustomFormatBacking As String = ""
    Private FormatBacking As DateTimePickerFormat = DateTimePickerFormat.Long

    <DefaultValue(True)> _
    <Bindable(True)> _
    Public Property NullDate() As Boolean
        Get
            Return Not Me.Checked
        End Get
        Set(ByVal value As Boolean)
            Me.Checked = Not value
        End Set
    End Property

    <DefaultValue("")> _
    <Localizable(True)> _
    <RefreshProperties(RefreshProperties.Repaint)> _
    Public Shadows Property CustomFormat() As String
        Get
            Return CustomFormatBacking
        End Get
        Set(ByVal value As String)
            CustomFormatBacking = value
            If DesignMode Or Not NullDate Then MyBase.CustomFormat = value
        End Set
    End Property

    <RefreshProperties(RefreshProperties.Repaint)> _
    Public Shadows Property Format() As DateTimePickerFormat
        Get
            Return FormatBacking
        End Get
        Set(ByVal value As DateTimePickerFormat)
            FormatBacking = value
            If DesignMode Or Not NullDate Then MyBase.Format = value
        End Set
    End Property

    <DefaultValue(true)> _
    <Bindable(True)> _
    <DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
    Public Shadows Property Checked() As Boolean
        Get
            Return MyBase.Checked
        End Get
        Set(ByVal value As Boolean)
            MyBase.Checked = value
        End Set
    End Property

    Private Sub updateNullState()
        If NullDate and Not DesignMode Then
            MyBase.CustomFormat = " "
            MyBase.Format = DateTimePickerFormat.Custom
        Else
            MyBase.CustomFormat = CustomFormatBacking
            MyBase.Format = FormatBacking
        End If
    End Sub

    Public Sub BeginInit() Implements System.ComponentModel.ISupportInitialize.BeginInit
    End Sub

    Public Sub EndInit() Implements System.ComponentModel.ISupportInitialize.EndInit
        updateNullState()
    End Sub

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

End Class