I have for the first time used datetimepicker control in my project. Although it is a great control I found it useless because of two things that are related:
- Default value cannot be set to nothing (null in C#).
- Datetimepicker canot display null (nothing in VB) values.
When I checked the msdn there was a caution notice saying just that.
I checked the codeproject website to look for an alternative. I found this control that suited my needs I only changed it to recognize the DateTime.MinValue to be nothing and set default to nothing. What I liked about it that it was the extended control, so it kept all the nice things I liked about default control. Here it is:
Imports System Imports System.ComponentModel Imports System.Globalization Imports System.Runtime.InteropServices Imports System.Threading Imports System.Windows.Forms ' Copyright (c) 2005 Claudio Grazioli, http://www.grazioli.ch ' ' This code is free software; you can redistribute it and/or modify it. ' However, this header must remain intact and unchanged. Additional ' information may be appended after this header. Publications based on ' this code must also include an appropriate reference. ' ' This code is distributed in the hope that it will be useful, but ' WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ' or FITNESS FOR A PARTICULAR PURPOSE. ' ''' <summary> ''' Represents a Windows date time picker control. It enhances the .NET standard <b>DateTimePicker</b> ''' control with the possibility to show empty values (null values). ''' </summary> <ComVisible(False)> _ Public Class DateTimePickerCtrl Inherits System.Windows.Forms.DateTimePicker #Region "Member variables" ' true, when no date shall be displayed (empty DateTimePicker) Private _isNull As Boolean ' If _isNull = true, this value is shown in the DTP Private _nullValue As String ' The format of the DateTimePicker control Private _format As DateTimePickerFormat = DateTimePickerFormat.[Long] ' The custom format of the DateTimePicker control Private _customFormat As String ' The format of the DateTimePicker control as string Private _formatAsString As String #End Region #Region "Constructor" ''' <summary> ''' Default Constructor ''' </summary> Public Sub New() MyBase.New() MyBase.Format = DateTimePickerFormat.[Custom] NullValue = " " Format = DateTimePickerFormat.[Long] End Sub #End Region #Region "Public properties" ''' <summary> ''' Gets or sets the date/time value assigned to the control. ''' </summary> ''' <value>The DateTime value assigned to the control ''' </value> ''' <remarks> ''' <p>If the <b>Value</b> property has not been changed in code or by the user, it is set ''' to the current date and time (<see cref="DateTime.Now"/>).</p> ''' <p>If <b>Value</b> is <b>null</b>, the DateTimePicker shows ''' <see cref="NullValue"/>.</p> ''' </remarks> <Bindable(True)> _ <Browsable(False)> _ Public Shadows Property Value() As [Object] Get If _isNull Then Return Nothing Else Return DateTime.MinValue End If End Get Set(ByVal value As [Object]) If value Is Nothing OrElse value Is DBNull.Value OrElse (value.GetType() Is GetType(DateTime) And CDate(value) = DateTime.MinValue) OrElse (CDate(value) = New Date(CType(0, Long))) Then SetToNullValue() Else SetToDateTimeValue() MyBase.Value = DirectCast(value, DateTime) End If End Set End Property ''' <summary> ''' Gets or sets the format of the date and time displayed in the control. ''' </summary> ''' <value>One of the <see cref="DateTimePickerFormat"/> values. The default is ''' <see cref="DateTimePickerFormat.Long"/>.</value> <Browsable(True)> _ <DefaultValue(DateTimePickerFormat.[Long]), TypeConverter(GetType([Enum]))> _ Public Shadows Property Format() As DateTimePickerFormat Get Return _format End Get Set(ByVal value As DateTimePickerFormat) _format = value If Not _isNull Then SetFormat() End If OnFormatChanged(EventArgs.Empty) End Set End Property ''' <summary> ''' Gets or sets the custom date/time format string. ''' <value>A string that represents the custom date/time format. The default is a null ''' reference (<b>Nothing</b> in Visual Basic).</value> ''' </summary> Public Shadows Property CustomFormat() As [String] Get Return _customFormat End Get Set(ByVal value As [String]) _customFormat = value End Set End Property ''' <summary> ''' Gets or sets the string value that is assigned to the control as null value. ''' </summary> ''' <value>The string value assigned to the control as null value.</value> ''' <remarks> ''' If the <see cref="Value"/> is <b>null</b>, <b>NullValue</b> is ''' shown in the <b>DateTimePicker</b> control. ''' </remarks> <Browsable(True)> _ <Category("Behavior")> _ <Description("The string used to display null values in the control")> _ <DefaultValue(" ")> _ Public Property NullValue() As [String] Get Return _nullValue End Get Set(ByVal value As [String]) _nullValue = value End Set End Property #End Region #Region "Private methods/properties" ''' <summary> ''' Stores the current format of the DateTimePicker as string. ''' </summary> Private Property FormatAsString() As String Get Return _formatAsString End Get Set(ByVal value As String) _formatAsString = value MyBase.CustomFormat = value End Set End Property ''' <summary> ''' Sets the format according to the current DateTimePickerFormat. ''' </summary> Private Sub SetFormat() Dim ci As CultureInfo = Thread.CurrentThread.CurrentCulture Dim dtf As DateTimeFormatInfo = ci.DateTimeFormat Select Case _format Case DateTimePickerFormat.[Long] FormatAsString = dtf.LongDatePattern Exit Select Case DateTimePickerFormat.[Short] FormatAsString = dtf.ShortDatePattern Exit Select Case DateTimePickerFormat.Time FormatAsString = dtf.ShortTimePattern Exit Select Case DateTimePickerFormat.[Custom] FormatAsString = Me.CustomFormat Exit Select End Select End Sub ''' <summary> ''' Sets the <b>DateTimePicker</b> to the value of the <see cref="NullValue"/> property. ''' </summary> Private Sub SetToNullValue() _isNull = True MyBase.CustomFormat = If((_nullValue Is Nothing OrElse _nullValue = [String].Empty), " ", "'" & _nullValue & "'") End Sub ''' <summary> ''' Sets the <b>DateTimePicker</b> back to a non null value. ''' </summary> Private Sub SetToDateTimeValue() If _isNull Then SetFormat() _isNull = False MyBase.OnValueChanged(New EventArgs()) End If End Sub #End Region #Region "Events" ''' <summary> ''' This member overrides <see cref="Control.WndProc"/>. ''' </summary> ''' <param name="m"></param> Protected Overloads Overrides Sub WndProc(ByRef m As Message) If _isNull Then If m.Msg = &H4E Then ' WM_NOTIFY Dim nm As NMHDR = DirectCast(m.GetLParam(GetType(NMHDR)), NMHDR) If nm.Code = -746 OrElse nm.Code = -722 Then ' DTN_CLOSEUP || DTN_? SetToDateTimeValue() End If End If End If MyBase.WndProc(m) End Sub <StructLayout(LayoutKind.Sequential)> _ Private Structure NMHDR Public HwndFrom As IntPtr Public IdFrom As Integer Public Code As Integer End Structure ''' <summary> ''' This member overrides <see cref="Control.OnKeyDown"/>. ''' </summary> ''' <param name="e"></param> Protected Overloads Overrides Sub OnKeyUp(ByVal e As KeyEventArgs) If e.KeyCode = Keys.Delete Then Me.Value = Nothing OnValueChanged(EventArgs.Empty) End If MyBase.OnKeyUp(e) End Sub Protected Overloads Overrides Sub OnValueChanged(ByVal eventargs As EventArgs) MyBase.OnValueChanged(eventargs) End Sub #End Region End Class
2 comments:
I like your DTP control and I'm trying to use it in a project.
The control id bound to sql server.
When I want to insert a new record, I'd like the DTP to be blank initially so the user knows they need to Enter a date.
They press a button to create a new record and to make the DTP show no value I use this code:
Me.DateBox2.Value = Nothing
but then the user can't enter a date, either by clicking on the calender or by entering via keyboard.
Any ideas?
Thanks for this code.
Post a Comment