自定义控件之DataGridView列(日期时间选择列)

效果图:

代码:

Imports System
Imports System.Windows.Forms

Public Class CalendarColumn
Inherits DataGridViewColumn

Public Sub New()
MyBase.New(New CalendarCell())
End Sub

Public Overrides Property CellTemplate() As DataGridViewCell
Get
Return MyBase.CellTemplate
End Get
Set(ByVal value As DataGridViewCell)
If Not (value Is Nothing) AndAlso Not value.GetType().IsAssignableFrom(GetType(CalendarCell)) Then
Throw New InvalidCastException("Must be a CalendarCell")
End If
MyBase.CellTemplate = value
End Set
End Property

End Class

Public Class CalendarCell
Inherits DataGridViewTextBoxCell

Public Sub New()
Me.Style.Format = "d"
End Sub

Public Overrides Sub InitializeEditingControl(ByVal rowIndex As Integer, ByVal initialFormattedValue As Object, ByVal dataGridViewCellStyle As DataGridViewCellStyle)
MyBase.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle)

Dim ctl As CalendarEditingControl = CType(DataGridView.EditingControl, CalendarEditingControl)
ctl.Text = CType(Me.Value, String)
End Sub

Public Overrides ReadOnly Property EditType() As Type
Get
Return GetType(CalendarEditingControl)
End Get
End Property

Public Overrides ReadOnly Property ValueType() As Type
Get
Return GetType(DateTime)
End Get
End Property

Public Overrides ReadOnly Property DefaultNewRowValue() As Object
Get
Return DateTime.Now
End Get
End Property

End Class

Class CalendarEditingControl
Inherits DateTimePicker
Implements IDataGridViewEditingControl

Private dataGridView As DataGridView
Private Shadows ValueChanged As Boolean = False
Private rowIndexNum As Integer

Public Sub New()
Me.Format = DateTimePickerFormat.Short
End Sub

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

Private Sub NotifyDataGridViewOfValueChange()
valueChanged = True
DataGridView.NotifyCurrentCellDirty(True)
End Sub

Public Property EditingControlFormattedValue() As Object Implements IDataGridViewEditingControl.EditingControlFormattedValue
Get
Return Me.Text
End Get
Set(ByVal value As Object)
Me.Text = value.ToString
Call NotifyDataGridViewOfValueChange()
End Set
End Property

Public Function GetEditingControlFormattedValue(ByVal context As DataGridViewDataErrorContexts) As Object Implements IDataGridViewEditingControl.GetEditingControlFormattedValue
Return Me.Text
End Function

Public Sub ApplyCellStyleToEditingControl(ByVal dataGridViewCellStyle As DataGridViewCellStyle) Implements IDataGridViewEditingControl.ApplyCellStyleToEditingControl
Me.Font = dataGridViewCellStyle.Font
Me.CalendarForeColor = dataGridViewCellStyle.ForeColor
Me.CalendarMonthBackground = dataGridViewCellStyle.BackColor
End Sub

Public Property EditingControlRowIndex() As Integer Implements IDataGridViewEditingControl.EditingControlRowIndex
Get
Return rowIndexNum
End Get
Set(ByVal value As Integer)
rowIndexNum = value
End Set
End Property

Public Function EditingControlWantsInputKey(ByVal key As Keys, ByVal dataGridViewWantsInputKey As Boolean) As Boolean Implements IDataGridViewEditingControl.EditingControlWantsInputKey
' Let the DateTimePicker handle the keys listed.
Select Case key And Keys.KeyCode
Case Keys.Left, Keys.Up, Keys.Down, Keys.Right, Keys.Home, Keys.End, Keys.PageDown, Keys.PageUp
Return True
Case Else
Return False
End Select
End Function

Public Sub PrepareEditingControlForEdit(ByVal selectAll As Boolean) Implements IDataGridViewEditingControl.PrepareEditingControlForEdit
' No preparation needs to be done.
End Sub

Public ReadOnly Property RepositionEditingControlOnValueChange() As Boolean Implements IDataGridViewEditingControl.RepositionEditingControlOnValueChange
Get
Return False
End Get
End Property

Public Property EditingControlDataGridView() As DataGridView Implements IDataGridViewEditingControl.EditingControlDataGridView
Get
Return dataGridView
End Get
Set(ByVal value As DataGridView)
dataGridView = value
End Set
End Property

Public Property EditingControlValueChanged() As Boolean Implements IDataGridViewEditingControl.EditingControlValueChanged
Get
Return valueChanged
End Get
Set(ByVal value As Boolean)
valueChanged = value
End Set
End Property

Public ReadOnly Property EditingControlCursor() As Cursor Implements IDataGridViewEditingControl.EditingPanelCursor
Get
Return MyBase.Cursor
End Get
End Property

End Class