DataGridView TimePicker [VB.NET]

218 阅读2分钟
Imports System
Imports System.Windows.Forms
''' <summary>
''' 用于DGV 的DateTime选择器
''' </summary>
Public Class DateTimePickerColumn
    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)

            ' 确保输入的是CalendarCell.类型
            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 = DateFormat.LongTime '"hh:mm:ss"
    End Sub

    Public Sub New(format As String)
        ' 自己定现实的格式
        Me.Style.Format = format
    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的对应属性
        
        '用来调整数字的增/减键
        ctl.ShowUpDown = True

        '因为DateTime格式必须要有日期,随便给个日期
        Dim tmp = DateTime.Now.Date + " " + Me.Value
        Dim x = tmp.ToString.Split(" ")
        If x.Length > 2 Then
            tmp = x(x.Length - 2) + " " + x(x.Length - 1)
        End If
        ctl.Value = CType(tmp, DateTime)
        ctl.Format = DateTimePickerFormat.Custom
        ctl.CustomFormat = "hh:mm:ss"
        'If DateTime.TryParse(Me.Value, ctl.Value) = True Then
        '    ctl.Value = CType(Me.Value, DateTime)
        'Else
        '    ctl.Value = Nothing
        'End If


    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
            ' 把00:00:00作为默认值,但是这个默认值是保存不了的,因为比DateTime最小值还小
            Return "00:00:00" 
        End Get
    End Property

End Class

Class CalendarEditingControl
    Inherits DateTimePicker
    Implements IDataGridViewEditingControl

    Private dataGridViewControl As DataGridView
    Private valueIsChanged As Boolean = False
    Private rowIndexNum As Integer

    Public Sub New()
        Me.Format = DateTimePickerFormat.Custom
        Me.CustomFormat = "hh:mm:ss"
    End Sub

    Public Property EditingControlFormattedValue() As Object Implements IDataGridViewEditingControl.EditingControlFormattedValue

        Get
            Return Me.Value.ToLongTimeString()
        End Get

        Set(ByVal value As Object)
            If TypeOf value Is [String] Then
                Me.Value = DateTime.Parse(CStr(value))
            End If
        End Set

    End Property

    Public Function GetEditingControlFormattedValue(ByVal context As DataGridViewDataErrorContexts) As Object _
Implements IDataGridViewEditingControl.GetEditingControlFormattedValue

        Return Me.Value.ToLongTimeString()

    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

        '避免失去焦点
        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

       
    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 dataGridViewControl
        End Get
        Set(ByVal value As DataGridView)
            dataGridViewControl = value
        End Set

    End Property

    Public Property EditingControlValueChanged() As Boolean Implements IDataGridViewEditingControl.EditingControlValueChanged

        Get
            Return valueIsChanged
        End Get
        Set(ByVal value As Boolean)
            valueIsChanged = value
        End Set

    End Property

    Public ReadOnly Property EditingControlCursor() As Cursor _
Implements IDataGridViewEditingControl.EditingPanelCursor

        Get
            Return MyBase.Cursor
        End Get

    End Property

    Protected Overrides Sub OnValueChanged(ByVal eventargs As EventArgs)

        '通知一下值变了
        valueIsChanged = True
        Me.EditingControlDataGridView.NotifyCurrentCellDirty(True)
        MyBase.OnValueChanged(eventargs)

    End Sub

End Class