Imports System.ComponentModel '----------------------------------------------------------- 'Class name : DateTimePickerEx 'Description: Extends the datetimepicker class to allow binding a DBNull database value ' to it. ' ' This class uses the display format to simulate an "empty" selection since the ' base datetimepicker class doesn't support displaying an empty text string. ' ' Since DBNull is not compatible with Date datatype, I created a new method called ' NullableValue to support it. 'History : '----------------------------------------------------------- Public Class DateTimePickerEx Inherits System.Windows.Forms.DateTimePicker 'Public Property _value As String = Nothing Public Property _value As String Get If Not Me.Checked Then Return "" Else Return (Me.Value) End If End Get Set(ByVal newValue As String) If newValue Is DBNull.Value Or newValue = "" Then ' MsgBox("null") Me.NullableValue = DBNull.Value Me.Checked = False Else 'MsgBox(newValue) Me.NullableValue = newValue End If End Set End Property Private m_enmOriginalFormat As Windows.Forms.DateTimePickerFormat Private m_strOriginalCustomFormat As String Private m_blnRefreshing As Boolean = False #Region " Windows Form Designer generated code " Public Sub New() MyBase.New() 'This call is required by the Windows Form Designer. InitializeComponent() 'Add any initialization after the InitializeComponent() call InitializeMembers() End Sub 'UserControl overrides dispose to clean up the component list. Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) If disposing Then If Not (components Is Nothing) Then components.Dispose() End If End If MyBase.Dispose(disposing) End Sub 'Required by the Windows Form Designer Private components As System.ComponentModel.IContainer 'NOTE: The following procedure is required by the Windows Form Designer 'It can be modified using the Windows Form Designer. 'Do not modify it using the code editor. _ Private Sub InitializeComponent() components = New System.ComponentModel.Container End Sub #End Region #Region " Event Declarations " Public Event NullableValueChanged As EventHandler '----------------------------------------------------------- 'Description: Raise the NullableValueChanged event. ' Required for "Bindable" properties. 'Return : 'Parameters : 'History : '----------------------------------------------------------- Protected Overridable Sub OnNullableValueChanged(ByVal e As EventArgs) RaiseEvent NullableValueChanged(Me, e) End Sub #End Region #Region " Public Methods and Properties " '----------------------------------------------------------- 'Description: Gets or Sets the date time picker value. ' Accepts DBNull values. 'Return : 'Parameters : 'History : '----------------------------------------------------------- _ Public Property NullableValue() As Object Get If Not Me.Checked Then Return (DBNull.Value) Else Return (Me.Value) End If End Get Set(ByVal newValue As Object) Dim blnRaiseEvent As Boolean = False If newValue Is DBNull.Value Then 'If the value changed If Me.Checked Then Me.Checked = False Me.RefreshText() blnRaiseEvent = True End If ElseIf IsDate(newValue) Then 'If only the "Checked" state changes (newValue parameter is equal to the Value property) 'We must raise the NullableValueChanged event manually since the parents ValueChanged 'event won't be fired. blnRaiseEvent = (Not Me.Checked) And (CType(newValue, Date).Equals(Me.Value)) Me.Checked = True Me.Value = CType(newValue, Date) Me.RefreshText() Else Throw New ArgumentException End If If blnRaiseEvent Then Me.OnNullableValueChanged(New EventArgs) End If End Set End Property #End Region #Region " Base Class Overrides " '----------------------------------------------------------- 'Description: When the user changes the value, we need to refresh ' the display text formats and to throw our NullableValueChanged event. 'Return : 'Parameters : 'History : '----------------------------------------------------------- Protected Overrides Sub OnValueChanged(ByVal e As System.EventArgs) Me.RefreshText() 'When the value changes, the nullable value also changes. Me.OnNullableValueChanged(e) MyBase.OnValueChanged(e) End Sub '----------------------------------------------------------- 'Description: If the format is changed we need to get the ' new format and store it as the new original format. 'Return : 'Parameters : 'History : '----------------------------------------------------------- Protected Overrides Sub OnFormatChanged(ByVal e As System.EventArgs) 'If the format changes because of our RefreshText method, we don't want to save 'the "temporary" format used to hide text as our original format... If Not m_blnRefreshing Then Me.SaveOriginalFormats() End If MyBase.OnFormatChanged(e) End Sub '----------------------------------------------------------- 'Description: When the control is ask to refresh itself, we also ' refresh the display format. 'Return : 'Parameters : 'History : '----------------------------------------------------------- Public Overrides Sub Refresh() Me.RefreshText() MyBase.Refresh() End Sub #End Region '----------------------------------------------------------- 'Description: Initialize the member variables. 'Return : 'Parameters : 'History : '----------------------------------------------------------- Private Sub InitializeMembers() Me.SaveOriginalFormats() 'The default for the DateTimePickerEx is to display the checkbox. MyBase.ShowCheckBox = False End Sub '----------------------------------------------------------- 'Description: Save the current display formats. 'Return : 'Parameters : 'History : '----------------------------------------------------------- Private Sub SaveOriginalFormats() m_enmOriginalFormat = Me.Format m_strOriginalCustomFormat = Me.CustomFormat End Sub '----------------------------------------------------------- 'Description: Restore the original display formats 'Return : 'Parameters : 'History : '----------------------------------------------------------- Private Sub RestoreOriginalFormats() Me.CustomFormat = m_strOriginalCustomFormat Me.Format = m_enmOriginalFormat End Sub '----------------------------------------------------------- 'Description: Refresh the display format based on the current state ' (Checked or not) 'Return : 'Parameters : 'History : '----------------------------------------------------------- Private Sub RefreshText() m_blnRefreshing = True If Me.Checked Then Me.RestoreOriginalFormats() Else Me.Format = Windows.Forms.DateTimePickerFormat.Custom Me.CustomFormat = " " End If m_blnRefreshing = False End Sub End Class