首页 文章

WinForm DateTimePicker蓝调 . 那是我吗?

提问于
浏览
4

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

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

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

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

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

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

编辑:

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

4 回答

  • 1

    做得有点棘手 . 这看起来不错:

    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
    
  • 1

    我有同样的问题 . 嗯,实际上我很聪明,但我的用户遇到了问题 .

    我解决了删除复选框,并添加2个单选按钮 . 现在看起来像这样:

    (使用伪UI)

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

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

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

    PS:当组合框具有焦点时,用户会抱怨的下一件事就是使用滚轮 .

  • 0

    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
    
  • 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
    

相关问题