Click here to Skip to main content
13,256,123 members (41,768 online)
Click here to Skip to main content
Add your own
alternative version


22 bookmarked
Posted 11 Aug 2011

TimeEdit Controls

, 25 Sep 2011
Rate this:
Please Sign up or sign in to vote.
TimeEdit, TimeCombo, TimeColumn for flexible time editing


Similar controls:

  1. System.Windows.Forms.DateTimePicker
  2. gTimePicker

How this control differ:

Features comparison:

Value UpdateOn Mask complete
On Lost focus
On validated
On Lost focus
On validated
Immediately after key press
Text and Value is
always the same
Null Value SupportNoYesYes
could have time only value:
like 0001/01/01 01:00
Has a dropdown clockNoYesIn TimeCombo 
It is not needed to use : or arrows
when entering time

Value after key press:

Example displayed Text00:0000:0000:00
Displayed text after pressing [6] Key6:0060:0006:00
Value after pressing [6] Key00:00 + current date00:0006:00
Value after lost focus06:00 + current date  06:0006:00

Why I Decided to Create It

I need a control that has the following features:

  1. Value property can be set to time only value such as 00:00 (0001/01/01 00:00) witch is the minimum value for DateTime Type
  2. Value property can be DBNull.Value and this is useful for database binding
  3. Edit time that always it value reflect the displayed text
  4. Simple time entering by minimum typing
  5. Could the increase or decrease its value by mouse weal moving or by arrows pressing

Value Related Property of this Control

  1. Value                 (Object):                     DBNull   or WorkingDayDate and Time.
  2. NullableDateTime  (Nullable(of DateTime)): Nothing or WorkingDayDate and Time.
  3. NullableTime        (Nullable(of DateTime)): Nothing or Time.

What This Application Does and Why it is Useful

You could include this control in your application to get the following features:

  1. Allows your application user to enter a time in 24 hour or 12 hour mode
  2. Protects your application user from entering invalid time
  3. If your application check the value of this control it will always return the right value even before the control lost focus and this is useful to get the value changing as user typing.
  4. You could assigned TimeEdit control with a WorkingDayDateControl to return a date and time in a single property
  5. It is a simple control and it is inherits from a TextBox and easy to understand and could be devolved to another more complex control
  6. It is an alternative and more useable than DateTimePicker

What Problem is Solved

  1. When user changes the text of TimeEdit control, its value changes immediately even if it does not lose focus.
  2. TimeEdit control does not have a MinValue so it could point to time only value.
  3. It has a WorkingDayEndTime and WorkingDayDate property that is useful when used in appointment arrangement in a working day that continues after midnight
  4. It could be assigned to WorkingDayDateControl to get the date part form it and return the date and time in a single Value property

About TimeCombo and TimeColumn:


This control will act the same even if your local culture is differ than en-US. It always use AM PM and : even if your local culture is use others

What the Next Step

  1. Add a drop down button to display a clock to select time.
  2. Building an appointment grid to arrange appointments that could be continue after mid night without break sorting (00:00 will located after 23:59 when sorting by time

Using the Code

  1. You could TimeEdit control in your Windows application to mentioned time
  2. If you build a user control could use TimeConverter and DateConverter for your control property.

The Demo Application

The demo application comparing between DateTimePicker and TimeEdit control. Ther is 2 TimeEdit control the first one has WorkingDayEndTime property set to 00:00 and the second TimeEdit control its WorkingDayEndTime is set to 02:00. When typing in any TimeEdit control or in the DateTimePicker control the value of the control is shown the date of the second TimeEdit control is set to 0001/01/02 (yyyy/MM/dd) if the time typed is less that WorkingDayEndTime and this is useful when sorting time in an appointments arrangements.
It also contains DataGridView that use TimeColumn.

Points of Interest

How to Keep Value and Text the Same

To do so we don't store the value in a separate variable we use the displayed text to get the value. and when user is set the value programmatically this control will study the value:

  1. If new value is numeric it will considered as Hour; 6.5 will be converted to 06:30
  2. If new value is DateTime then the WorkingDayDate property will be set to the new value date and the NullabeTime property will be set to time part of the new value
  3. if new value is empty string then value will be DBNull
  4. if new value is string that contains time then the value will return its value
Public Overridable Property Value As Object
            If String.IsNullOrEmpty(MyBase.Text) Then
                Return DBNull.Value
                Return Me.NullableDateAndTime.Value
            End If
        Catch ex As Exception
            Return DBNull.Value
        End Try
    End Get
    Set(ByVal NewValue As Object)
            If IsNumeric(NewValue) Then
                'Nothing = 00:00
                'not include date
                Me.NullableTime = (New Date).AddHours(CDbl(NewValue))
            ElseIf IsDate(NewValue) Then
                'Nothing = 00:00
                'include date
                Me.NullableDateAndTime = CDate(NewValue)
            ElseIf IsDBNull(NewValue) OrElse NewValue Is Nothing Then
                Me.Text = ""
            ElseIf GetType(TimeSpan).IsAssignableFrom(NewValue.GetType) Then
                'not include date
                Me.NullableTime = New Date(CType(NewValue, TimeSpan).Ticks)
            ElseIf GetType(String).IsAssignableFrom(NewValue.GetType) Then
                If String.IsNullOrEmpty(CStr(NewValue)) Then
                    Me.Text = ""
                    'don't include date
                    Me.NullableTime = ToDateTime(CStr(NewValue))
                End If
                Me.Text = ""
            End If
        Catch ex As Exception
        End Try
    End Set
End Property

Validate Time Input and Protecting User from Entering Invalid Time

  1. Overrides Sub OnKeyPress
  2. If user press a key in an empty TimeEdit control then it will automatically assign with default value
  3. Build sText string that echo the user input result  
    Dim sText = Me.Text
    Mid(sText, Me.SelectionStart + 1, 1) = e.KeyChar 'Replace the 2d char
  4. Test if the resulting text is valid Time using Regular Expressions taking "^(?<Hour>([0-1]\d|2[0-3])):(?<Minute>[0-5]\d)$" for 24 hour mode and "^(?<Hour>(0?[1-9]|1[0-2])):(?<Minute>[0-5]\d) (?<AMPM>(A|P)M)$" for 12 hour mode
    * This Regular Expressions contains three groups Hour, Minute and AMPM
    * Each group has its rule example Hour in 12 hour mode is 0 followed by any digest or 1 followed by 0-2  
  5. If not match then study where the editing char in hours or in minutes and study its possible fixing as follwing code:  
    Private Sub OnHourKeyPress(ByRef e As KeyPressEventArgs)
            Dim Do1 = False
            Select Case SelectionStart
                Case 0 'SelectionStart = 0
                    Select Case e.KeyChar
                        Case "3"c To "9"c 'not allowed to be first char
                            Do1 = True
                        Case "2"c 'not allowed to be first char in 12 Hr mode
                            If Not _Hr24 Then
                                Do1 = True
                                'in 24 hr mode if the next char is > 3 then replace it with 3
                                If Me.Text()(1) > "3"c Then
                                    Mid(Me.Text, 2, 1) = "3"
                                End If
                            End If
                        Case "1"c
                            If Not _Hr24 Then
                                'in 12 hr mode if the next char is > 2 then replace it with 2
                                If Me.Text()(1) > "2"c Then
                                    Mid(Me.Text, 2, 1) = "2"
                                End If
                            End If
                    End Select
                Case 1 'SelectionStart = 1
                    Select Case MyBase.Text(0)
                        Case Is > "2"c
                            'in 12 hr mode not allowed to be in 2d char
                            If Not Hr24 Then
                                Do1 = True
                            End If
                        Case "2"c
                            If Me.Hr24 Then
                                Select Case e.KeyChar
                                    Case "4"c To "9"c
                                        'in 24 hr mode not allowed to be in 2d char
                                        Do1 = True
                                End Select
                                Do1 = True
                            End If
                        Case "1"c
                            If Not _Hr24 Then
                                Select Case e.KeyChar
                                    Case "3"c To "9"c
                                        Do1 = True
                                End Select
                            End If
                    End Select 'MyBase.Text(0)
            End Select
            If Do1 Then
                Me.Text = "0" & Me.Text.Substring(1)
                SelectionStart = 1
                SelectionLength = 1
            End If
        Catch ex As Exception
        End Try
    End Sub
TimeEdit control Inherits TextBox but it removes some properties by:
  1. Adding Designer attribute:
    <ToolboxItem(True), Designer(GetType(TimeEditDesigner)), _
    DefaultBindingProperty("Value")> _
    Public Class TimeEdit
        Inherits TextBox
        '....More Code....
        <DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), _
        Browsable(False), Obsolete("", True)> _
        Public Shadows Lines, Multiline, AutoCompleteMode, _
        AutoCompleteSource, AutoCompleteCustomSource, WordWrap, _
        PasswordChar, UseSystemPasswordChar As DBNull
    End Class
  2. Building TimeEditDesigner class:
    Imports System.Windows.Forms.Design
    Imports System.ComponentModel
    Public Class TimeEditDesigner
        Inherits ControlDesigner
        Protected Overrides Sub PreFilterProperties(ByVal properties As IDictionary)
            Catch ex As Exception
            End Try
        End Sub
        Public Overrides ReadOnly Property ActionLists As _
                Return Nothing
            End Get
        End Property
        Public Overrides ReadOnly Property Verbs As _
                Return Nothing
            End Get
        End Property
    End Class

How This Application Handle Run Time Errors

Every procedure has the following diagram

Private Sub OnHourKeyPress(ByRef e As KeyPressEventArgs) 'procedure start
    '.... procedure code
  	Catch ex As Exception
    End Try
End Sub 'procedure end

A module that containing ErrMsg procedure is added to the project to document every run time error happened in a file located in "C:\Temp"

The error is printed to that file using as follows:

FileOpen(iFile, sLogFileName, OpenMode.Append, OpenAccess.Write)
Print(iFile, vbNewLine & vbNewLine & "Date: " _
          & Now.ToString("yyyy/MM/dd HH:mm:ss") & vbNewLine)
Print(iFile, sMsg)


  • Initial version
  • Adding TimeCombo and TimeColumn


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Lebanon Lebanon
Look at your eyes:
There is a developer behind every piece of code!

Eyes are too complex what about them!

You may also be interested in...


Comments and Discussions

QuestionNice post Pin
Tridip Bhattacharjee13-Dec-13 0:12
memberTridip Bhattacharjee13-Dec-13 0:12 
AnswerRe: Nice post Pin
NewPast28-Dec-13 7:04
groupNewPast28-Dec-13 7:04 
GeneralMy vote of 5 Pin
SohjSolwin5-Oct-11 3:20
memberSohjSolwin5-Oct-11 3:20 
Questionnice Pin
CIDev6-Sep-11 6:03
memberCIDev6-Sep-11 6:03 
GeneralMy vote of 5 Pin
clivecarter33216-Aug-11 1:37
memberclivecarter33216-Aug-11 1:37 
GeneralMy vote of 5 Pin
SSDiver211211-Aug-11 16:52
memberSSDiver211211-Aug-11 16:52 
GeneralThanks Pin
chemnoor11-Aug-11 5:57
memberchemnoor11-Aug-11 5:57 
GeneralRe: Thanks Pin
Slacker00712-Aug-11 1:27
memberSlacker00712-Aug-11 1:27 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.171114.1 | Last Updated 25 Sep 2011
Article Copyright 2011 by NewPast
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid