Marshall
Marshall

Reputation: 648

custom datagridview column Control will not accept a period (.)

I cannot get a control I found online to accept a period(.). I need to be able to enter numeric values with decimal places. I wanted to use the numericupdown control in a datagridview cell so I can use the up-down arrows for adjusting values.

This control implments the NumericUpDown control as the editing control on a datagridview column. I found it online (don't remember where), and ti was based on a similar custom datagridview column based in a calendar control.

I made a few modifications to it so I could set the maximum, minimum, decimalplaces and imcrement properties.

However, even when decimal places is set to 2 and increment is .1, when I'm typing a value the control will not accept a period.

Below is the code, which includes the classes for the column, cell, and editing control. Please help. I have no clue what the problem is.

 

    Public Class NumericUpDownColumn
        Inherits DataGridViewColumn

        Public Sub New()
            MyBase.New(New NumericUpDownCell())

        End Sub

        Public Overrides Property CellTemplate() As DataGridViewCell
            Get
                Return MyBase.CellTemplate
            End Get
            Set(ByVal value As DataGridViewCell)

                ' Ensure that the cell used for the template is a CalendarCell.
                If Not (value Is Nothing) AndAlso _
                    Not value.GetType().IsAssignableFrom(GetType(NumericUpDownCell)) _
                    Then
                    Throw New InvalidCastException("Must be a CalendarCell")
                End If
                MyBase.CellTemplate = value

            End Set
        End Property
        Private _Maximum As Decimal = 100
        Private _Minimum As Decimal = 0
        Private _Increment As Decimal = 0.1
        Private _DecimalPlaces As Integer = 2

        Public Property DecimalPlaces() As Integer
            Get
                Return _DecimalPlaces
            End Get
            Set(ByVal value As Integer)
                If _DecimalPlaces = value Then
                    Return
                End If
                _DecimalPlaces = value
            End Set
        End Property

        Public Property Maximum() As Decimal
            Get
                Return _Maximum
            End Get
            Set(ByVal value As Decimal)
                _Maximum = value
            End Set
        End Property
         _
        Public Property Minimum() As Decimal
            Get
                Return _Minimum
            End Get
            Set(ByVal value As Decimal)
                _Minimum = value
            End Set

        End Property
         _
        Public Property Increment() As Decimal
            Get
                Return _Increment
            End Get
            Set(ByVal value As Decimal)
                _Increment = value
            End Set

        End Property
    End Class

 

    Public Class NumericUpDownCell
        Inherits DataGridViewTextBoxCell

        Public Sub New()
            ' Use the short date format.
            Me.Style.Format = "N2"
        End Sub


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

            ' Set the value of the editing control to the current cell value.
            MyBase.InitializeEditingControl(rowIndex, initialFormattedValue, _
                dataGridViewCellStyle)

            Dim ctl As NumericUpDownEditingControl = _
                CType(DataGridView.EditingControl, NumericUpDownEditingControl)
            RemoveHandler ctl.Enter, AddressOf Me.OnNumericEnter
            AddHandler ctl.Enter, AddressOf Me.OnNumericEnter
            ctl.Maximum = CType(Me.DataGridView.Columns(Me.ColumnIndex), NumericUpDownColumn).Maximum
            ctl.Minimum = CType(Me.DataGridView.Columns(Me.ColumnIndex), NumericUpDownColumn).Minimum
            ctl.Increment = CType(Me.DataGridView.Columns(Me.ColumnIndex), NumericUpDownColumn).Increment
            ctl.DecimalPlaces = CType(Me.DataGridView.Columns(Me.ColumnIndex), NumericUpDownColumn).DecimalPlaces
            ctl.ThousandsSeparator = True
            ctl.Value = CType(Me.Value, Decimal)

        End Sub
        ''' 
        ''' Handle on enter event of numeric
        ''' 
        ''' 
        ''' 
        ''' 
        Private Sub OnNumericEnter(ByVal sender As Object, ByVal e As EventArgs)
            Dim control As NumericUpDownEditingControl = CType(sender, NumericUpDownEditingControl)
            Dim strValue As String = control.Value.ToString("N2")
            control.Select(0, strValue.Length)
        End Sub

        Public Overrides ReadOnly Property EditType() As Type
            Get
                ' Return the type of the editing contol that CalendarCell uses.
                Return GetType(NumericUpDownEditingControl)
            End Get
        End Property

        Public Overrides ReadOnly Property ValueType() As Type
            Get
                ' Return the type of the value that CalendarCell contains.
                Return GetType(Decimal)
            End Get
        End Property

        Public Overrides ReadOnly Property DefaultNewRowValue() As Object
            Get
                ' Use the current date and time as the default value.
                Return 0
            End Get
        End Property

    End Class

 

    Class NumericUpDownEditingControl
        Inherits NumericUpDown
        Implements IDataGridViewEditingControl

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

        Public Sub New()



        End Sub

        Public Property EditingControlFormattedValue() As Object _
            Implements IDataGridViewEditingControl.EditingControlFormattedValue

            Get
                Return Me.Value.ToString("N2")
            End Get

            Set(ByVal value As Object)
                If TypeOf value Is Decimal Then
                    Me.Value = Decimal.Parse(value)
                End If
            End Set

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

            Return Me.Value.ToString("N2")

        End Function

        Public Sub ApplyCellStyleToEditingControl(ByVal dataGridViewCellStyle As _
            DataGridViewCellStyle) _
            Implements IDataGridViewEditingControl.ApplyCellStyleToEditingControl

            Me.Font = dataGridViewCellStyle.Font
            Me.ForeColor = dataGridViewCellStyle.ForeColor
            Me.BackColor = 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
                Case Keys.Up, Keys.Down

                    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 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)

            ' Notify the DataGridView that the contents of the cell have changed.
            valueIsChanged = True
            Me.EditingControlDataGridView.NotifyCurrentCellDirty(True)
            MyBase.OnValueChanged(eventargs)

        End Sub

    End Class

Upvotes: 0

Views: 543

Answers (1)

Marshall
Marshall

Reputation: 648

I used an old programmers trick to solve this. I just downloaded the sample code from the post Plutonix referenced and just added the DLL it came with to my project. This work fine and saved me a lot of trouble I wasn't looking for.

Upvotes: 0

Related Questions