[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Error handling in datagridview cell editing.

Posted on 2008-11-18
43
Medium Priority
?
4,114 Views
Last Modified: 2012-05-05
Hi,

I use datagridview cell to do editing.

There some fields required numeric input, how to handling wrong edit without showing error or get exception like :

If not isnumeric(cell.value) then cell.value= 0

Thank you.
0
Comment
Question by:emi_sastra
  • 20
  • 15
  • 6
  • +1
43 Comments
 
LVL 6

Expert Comment

by:M3mph15
ID: 22991790
If Not IsNumeric(GridView1.Rows([rowindex]).Cells([cellindex]).Text) Then
                  GridView1.Rows([rowindex]).Cells([cellindex]).Text = 0
End If
0
 
LVL 1

Author Comment

by:emi_sastra
ID: 22991819
No, it is not work.
Where to put the checking?

Still get error:

Operation did not succeed because the program cannot commit or quit a cell value change.  

Thank you.
0
 
LVL 6

Expert Comment

by:M3mph15
ID: 22991869
Try doing the checking in the RowUpdating event
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 48

Expert Comment

by:jpaulino
ID: 22992230
Try something like this:
    Private Sub DataGridView1_CellEndEdit(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellEndEdit
        ' Checks if the column is the second one (zero based index)
        If e.ColumnIndex = 1 Then
 
            Dim result As Integer
            If Not Integer.TryParse(Me.DataGridView1(e.ColumnIndex, e.RowIndex).Value.ToString, result) Then
                Me.DataGridView1(e.ColumnIndex, e.RowIndex).Value = 0
            End If
 
        End If
    End Sub

Open in new window

0
 
LVL 1

Author Comment

by:emi_sastra
ID: 23000904
Hi M3mph15,

How to check it?

Thank you.
0
 
LVL 1

Author Comment

by:emi_sastra
ID: 23000908
Hi jpaulino,

How to check if the problem is on certain column?

Thank you.
0
 
LVL 1

Author Comment

by:emi_sastra
ID: 23000953
Hi jpaulino,

i use ProcessCmdKey.

 Case EnumGridViewColumn.NilaiTransaksi

                        If Not IsNumeric(dgvRow.Cells(.CurrentCell.ColumnIndex).Value) Then
                            dgvRow.Cells(.CurrentCell.ColumnIndex).Value = 0
                        End If

                        If dgvRow.Cells(.CurrentCell.ColumnIndex).Value < 0 Then
                            dgvRow.Cells(.CurrentCell.ColumnIndex).Value = 0
                        End If

                        If dgvRow.Cells("Keterangan").Value.ToString.Trim = "" Then
                            dgvRow.Cells("NilaiKurs").Value = CDbl(txtNilaiKurs.Text)
                        End If

                       'Exception at below code

                      .CurrentCell = .Rows(.CurrentCell.RowIndex).Cells(.CurrentCell.ColumnIndex + 1)


Thank you.
     

 
Private Sub dgvTransaksi_CellEndEdit(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvTransaksi.CellEndEdit
        ' Checks if the column is the second one (zero based index)
        If e.ColumnIndex > 0 Then
 
            Dim result As Integer
            If Not Integer.TryParse(Me.dgvTransaksi(e.ColumnIndex, e.RowIndex).Value.ToString, result) Then
                If e.ColumnIndex = EnumGridViewColumn.NilaiTransaksi Or _
                    e.ColumnIndex = EnumGridViewColumn.NilaiKurs Then
                    Me.dgvTransaksi(e.ColumnIndex, e.RowIndex).Value = 0
                End If
            End If
 
        End If
    End Sub

Open in new window

0
 
LVL 48

Expert Comment

by:jpaulino
ID: 23001907
>> How to check if the problem is on certain column?

If e.ColumnIndex = 1 Then check if you have changed on the column 1
 
>> i use ProcessCmdKey.
For what ? Do you have problems with your snippet ?
0
 
LVL 1

Author Comment

by:emi_sastra
ID: 23007863
If e.ColumnIndex = 1 Then check if you have changed on the column 1

Why should I check column 1 when the problem happened on other column?

Please see the problem where the exception exist.

   'Exception at below code

   .CurrentCell = .Rows(.CurrentCell.RowIndex).Cells(.CurrentCell.ColumnIndex + 1)

The code above is inside ProcessCmdKey procedure.

Thank you.
0
 
LVL 48

Expert Comment

by:jpaulino
ID: 23008491
>> Why should I check column 1 when the problem happened on other column?

Emi_sastra, ColumnIndex = 1 it's obviously and examples. You should change to the column where you want to validate.
You don't need to work on ProcessCmdKey
0
 
LVL 1

Author Comment

by:emi_sastra
ID: 23010241
You should change to the column where you want to validate.
Yes, that's why I change to :

Private Sub dgvTransaksi_CellEndEdit(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvTransaksi.CellEndEdit
        ' Checks if the column is the second one (zero based index)
        If e.ColumnIndex > 0 Then
 
            Dim result As Integer
            If Not Integer.TryParse(Me.dgvTransaksi(e.ColumnIndex, e.RowIndex).Value.ToString, result) Then
                If e.ColumnIndex = EnumGridViewColumn.NilaiTransaksi Or _
                    e.ColumnIndex = EnumGridViewColumn.NilaiKurs Then
                    Me.dgvTransaksi(e.ColumnIndex, e.RowIndex).Value = 0
                End If
            End If
 
        End If
    End Sub

You don't need to work on ProcessCmdKey.

Do you remember that you taught me how to entry data at datagridview and use Enter to move to another column or row? You recommend using ProcessCmdKey. I use it now, please see the more complete code. If there is any alternative I am happy to learn it.

Thank you.


  Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
        If Not blnGridOnFocus Then Exit Function
 
        If keyData = Keys.Enter Then
 
            With Me.dgvTransaksi
 
                .EndEdit(True)
 
                Dim dgvRow As DataGridViewRow
                dgvRow = .Rows(.CurrentRow.Index)
 
                Select Case .CurrentCell.ColumnIndex
 
                   
                    Case EnumGridViewColumn.NilaiTransaksi
 
                        If Not IsNumeric(dgvRow.Cells(.CurrentCell.ColumnIndex).Value) Then
                            dgvRow.Cells(.CurrentCell.ColumnIndex).Value = 0
                        End If
 
                        If dgvRow.Cells(.CurrentCell.ColumnIndex).Value < 0 Then
                            dgvRow.Cells(.CurrentCell.ColumnIndex).Value = 0
                        End If
 
                        If dgvRow.Cells("Keterangan").Value.ToString.Trim = "" Then
                            dgvRow.Cells("NilaiKurs").Value = CDbl(txtNilaiKurs.Text)
                        End If
 
                        Me.Count_Total()
 
                        .CurrentCell = .Rows(.CurrentCell.RowIndex).Cells(.CurrentCell.ColumnIndex + 1)
 
 
                    Case EnumGridViewColumn.Keterangan
 
                            If .Rows.Count > .CurrentRow.Index Then
 
                                If .CurrentCell.RowIndex + 1 = .RowCount Then ERV_Global.Add_New_Row(dtTDCASH)
 
                                If intMode = ERV_Global.MB_ADD Then
                                    .CurrentCell = .Rows(.CurrentCell.RowIndex + 1).Cells(EnumGridViewColumn.NamaRekanan)
                            Else
 
                                .CurrentCell = .Rows(.CurrentCell.RowIndex + 1).Cells(EnumGridViewColumn.NamaRekanan)
 
                                If .Rows(.CurrentCell.RowIndex).Cells(.CurrentCell.ColumnIndex).Value.ToString.Trim <> "" Then
                                    .CurrentCell = .Rows(.CurrentCell.RowIndex).Cells(EnumGridViewColumn.JenisTrs)
                                End If
                            End If
 
                        End If
 
                    Case Else
                            SendKeys.Send("{TAB}")
                            .CurrentCell = .Rows(.CurrentCell.RowIndex).Cells(.CurrentCell.ColumnIndex)
 
                End Select
 
                .BeginEdit(True)
                blnGridOnFocus = True
 
            End With
 
            Return True
        Else
            Return MyBase.ProcessCmdKey(msg, keyData)
        End If
 
    End Function

Open in new window

0
 
LVL 48

Expert Comment

by:jpaulino
ID: 23011091
>> Yes, that's why I change to :

This will validate ALL column starting in the first second one. Is this what you want ?
 
>> You recommend using ProcessCmdKey
That's two different thinks!
The first it's to capture the enter key on the datagridview to do something (in that case to change the behavior). This is perform some validation AFTER the user changes the data. This way you can use the build in events of the datagridview (CellEndEdit) to handle your validation. You cannot detect from the ProcessCmdKey if the user have changed a value in the cell.
0
 
LVL 1

Author Comment

by:emi_sastra
ID: 23011105
This will validate ALL column starting in the first second one. Is this what you want ?
No, so how to change it?

The first it's to capture the enter key on the datagridview to do something (in that case to change the behavior). This is perform some validation AFTER the user changes the data. This way you can use the build in events of the datagridview (CellEndEdit) to handle your validation. You cannot detect from the ProcessCmdKey if the user have changed a value in the cell.

Yes, I have trapped it in CellEndEdit event, but after that it back to inside ProcessCmdKey.
Operation did not succeed because the program cannot commit or quit a cell value change.  
Exception happened inside ProcessCmdKey under code  :
 .CurrentCell = .Rows(.CurrentCell.RowIndex).Cells(.CurrentCell.ColumnIndex + 1)

Thank you.
0
 
LVL 48

Expert Comment

by:jpaulino
ID: 23011140


>> No, so how to change it?

You need to use the columns you want to validate, like:
If e.ColumnIndex = 2 Or e.ColumnIndex = 4 Then
    ' your code
End If

This will validate the columns 3 and 5

Try this way and then let me know if the error in the ProcessCmdKey still occurs

 
0
 
LVL 1

Author Comment

by:emi_sastra
ID: 23011165
I change to :

If e.ColumnIndex = EnumGridViewColumn.NilaiTransaksi Or _
                  e.ColumnIndex = EnumGridViewColumn.NilaiKurs Then

            Dim result As Integer
            If Not Integer.TryParse(Me.dgvTransaksi(e.ColumnIndex, e.RowIndex).Value.ToString, result) Then
                Me.dgvTransaksi(e.ColumnIndex, e.RowIndex).Value = 0
            End If
        End If

The error still happens.

Thank you.

0
 
LVL 48

Expert Comment

by:jpaulino
ID: 23011216
>> The error still happens.
What errors ?

0
 
LVL 1

Author Comment

by:emi_sastra
ID: 23011268
Operation did not succeed because the program cannot commit or quit a cell value change.  
Exception happened inside ProcessCmdKey under code  :
 .CurrentCell = .Rows(.CurrentCell.RowIndex).Cells(.CurrentCell.ColumnIndex + 1)

Thank you.
0
 
LVL 18

Expert Comment

by:Priest04
ID: 23045247
Try this
If e.ColumnIndex = EnumGridViewColumn.NilaiTransaksi Or _
                  e.ColumnIndex = EnumGridViewColumn.NilaiKurs Then
 
            Dim result As Integer
            If Not Integer.TryParse(e.FormattedValue, result) Then
                e.Cancel = True
                SendKeys.Send("{ESC}")
                Me.dgvTransaksi(e.ColumnIndex, e.RowIndex).Value = 0
            End If
        End If

Open in new window

0
 
LVL 1

Author Comment

by:emi_sastra
ID: 23047249
Hi Priest04,

Still get the same error.

Thank you.
0
 
LVL 18

Expert Comment

by:Priest04
ID: 23048565
You cannot have the same error, O have tried the example on a grid with an int column and it is working. If yo do, there is ome insfo that you are not telling us.. Place a new datagridview,and try the example.

0
 
LVL 1

Author Comment

by:emi_sastra
ID: 23053020
Do you use below ProcessCmdKey in you code?

Thank you.
Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
        If Not blnGridOnFocus Then Exit Function
 
        If keyData = Keys.Enter Then
 
            With Me.dgvTransaksi
 
                .EndEdit(True)
 
                Dim dgvRow As DataGridViewRow
                dgvRow = .Rows(.CurrentRow.Index)
 
                Select Case .CurrentCell.ColumnIndex
 
                   
                    Case EnumGridViewColumn.NilaiTransaksi
 
                        If Not IsNumeric(dgvRow.Cells(.CurrentCell.ColumnIndex).Value) Then
                            dgvRow.Cells(.CurrentCell.ColumnIndex).Value = 0
                        End If
 
                        If dgvRow.Cells(.CurrentCell.ColumnIndex).Value < 0 Then
                            dgvRow.Cells(.CurrentCell.ColumnIndex).Value = 0
                        End If
 
                        If dgvRow.Cells("Keterangan").Value.ToString.Trim = "" Then
                            dgvRow.Cells("NilaiKurs").Value = CDbl(txtNilaiKurs.Text)
                        End If
 
                        Me.Count_Total()
 
                        .CurrentCell = .Rows(.CurrentCell.RowIndex).Cells(.CurrentCell.ColumnIndex + 1)
 
 
                    Case EnumGridViewColumn.Keterangan
 
                            If .Rows.Count > .CurrentRow.Index Then
 
                                If .CurrentCell.RowIndex + 1 = .RowCount Then ERV_Global.Add_New_Row(dtTDCASH)
 
                                If intMode = ERV_Global.MB_ADD Then
                                    .CurrentCell = .Rows(.CurrentCell.RowIndex + 1).Cells(EnumGridViewColumn.NamaRekanan)
                            Else
 
                                .CurrentCell = .Rows(.CurrentCell.RowIndex + 1).Cells(EnumGridViewColumn.NamaRekanan)
 
                                If .Rows(.CurrentCell.RowIndex).Cells(.CurrentCell.ColumnIndex).Value.ToString.Trim <> "" Then
                                    .CurrentCell = .Rows(.CurrentCell.RowIndex).Cells(EnumGridViewColumn.JenisTrs)
                                End If
                            End If
 
                        End If
 
                    Case Else
                            SendKeys.Send("{TAB}")
                            .CurrentCell = .Rows(.CurrentCell.RowIndex).Cells(.CurrentCell.ColumnIndex)
 
                End Select
 
                .BeginEdit(True)
                blnGridOnFocus = True
 
            End With
 
            Return True
        Else
            Return MyBase.ProcessCmdKey(msg, keyData)
        End If
 
    End Function

Open in new window

0
 
LVL 18

Expert Comment

by:Priest04
ID: 23053275
emi_sastra, the conversation is not going anywhere. I am giving you one code, you are returning yours.... And you cannot have it both ways. First of all, ProcessCmdKey is not a place where you would put your business logic. For that purpose events like CellValidating, CellEndEdit and similar are used.

I don't see any reason why you would handle this in the ProcessCmdKey event. Do you? If you do, I would like to know why?

The code I gave you to handle non numeric values is doing what you wanted to - it sets value to 0 when non numeric value is used.
0
 
LVL 1

Author Comment

by:emi_sastra
ID: 23053412
emi_sastra, the conversation is not going anywhere. I am giving you one code, you are returning yours.... And you cannot have it both ways. First of all, ProcessCmdKey is not a place where you would put your business logic. For that purpose events like CellValidating, CellEndEdit and similar are used.

I am not going any where, but the fact is I am using it. I just want to know whether the way I do cause the problem or not?

I don't see any reason why you would handle this in the ProcessCmdKey event. Do you? If you do, I would like to know why?
I have try any other event to move from one cell to next cell using Enter, but I can not get solution from EE, and later jpaulino taught me to do that and so far I am happy with it except this problem.

The code I gave you to handle non numeric values is doing what you wanted to - it sets value to 0 when non numeric value is used.

Please see the run sequence:

After I enter not numeric key to the cell  and Press Enter to the cell then It goes to :

1. ProcessCmdKey
2. CellLeave
3. CellValidating
4. CellValueChange
5. CellEnter
5. ProcessCmdKey at .CurrentCell = .Rows(.CurrentCell.RowIndex).Cells(.CurrentCell.ColumnIndex + 1) where the exception occurs.

The code you provide has 2 problem:

1. I have to add event below, otherwise will cause error.
       Private Sub dgvTransaksi_DataError(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewDataErrorEventArgs) Handles dgvTransaksi.DataError
        e.Cancel = True
        e.ThrowException = False

    End Sub

2. SendKeys.Send("{ESC}") cause hanging, I have to press Ctrl Alt Del to make it process the next line which is   Me.dgvTransaksi(e.ColumnIndex, e.RowIndex).Value = 0.

Thank you.



Private Sub dgvTransaksi_CellValueChanged(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles _
                dgvTransaksi.CellValueChanged
 
        If Not blnAllowGridValidation Then Exit Sub
 
        With dgvTransaksi
 
            If e.ColumnIndex = EnumGridViewColumn.NilaiTransaksi Or _
               e.ColumnIndex = EnumGridViewColumn.NilaiKurs Then
 
                Dim dgvRow As DataGridViewRow = .Rows(.CurrentRow.Index)
 
                If Not IsNumeric(dgvRow.Cells(e.ColumnIndex).Value) Then
                    dgvRow.Cells(e.ColumnIndex).Value = 0
                End If
 
                Count_Total()
            End If
 
        End With
 
    End Sub
 
 Private Sub dgvTransaksi_CellLeave(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvTransaksi.CellLeave
        blnGridOnFocus = False
 
        If intMode = ERV_Global.MB_VIEW Then Exit Sub
 
        With dgvTransaksi
 
            If e.ColumnIndex = 1 Then
                .Rows(e.RowIndex).Cells(e.ColumnIndex).Style.BackColor = .Rows(e.RowIndex).Cells(2).Style.BackColor
            Else
                .Rows(e.RowIndex).Cells(e.ColumnIndex).Style.BackColor = .Rows(e.RowIndex).Cells(1).Style.BackColor
            End If
 
        End With
    End Sub
 
 Private Sub dgvTransaksi_CellEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvTransaksi.CellEnter
        If intMode = ERV_Global.MB_VIEW Then Exit Sub
 
        If Not blnAllowGridValidation Then Exit Sub
 
        blnGridOnFocus = True
 
        With dgvTransaksi
            .Rows(e.RowIndex).Cells(e.ColumnIndex).Style.BackColor = ERV_Global.Get_LostFocus_Color()
        End With
    End Sub

Open in new window

0
 
LVL 18

Accepted Solution

by:
Priest04 earned 2000 total points
ID: 23054986
> I don't see any reason why you would handle this in the ProcessCmdKey event. Do you? If you do, I would like to know why?
>>I have try any other event to move from one cell to next cell using Enter, but I can not get solution from EE, and later jpaulino taught me to do that and so far I am happy with it except this problem.

THe problem is, if you use ProcessCmdKey for purpose of moving to the next cell, you shouldnt be now using it for everything else. This is not what it is meant for.

I, for example, also use ProcessCmdKey event to override the default behavior of Enter key when you are in edit mode (it moves to the next cell bellow), where I implement logic which leaves the focus to the cell which is edited. Now, I have some property which is called CellEditEnterBehavior, whicih has two values, Defualt and None, so I can easily choose weather I will use default implementation or my custom implementation. I choose not to move to the next cell in the same row, because in many cases I have to skip some column, and I can with ease move to any cell I want in the CellEndEdit cell, just by setting column index.

I am explaining all this, because if it is done this way, you can reuse this custom datagridview in ANY project. You dont need to have one for projectA, and one for ProjectB, etc, so you will have some duplicate code for each project. And what if in some point you see that there is some wrong code logic that you have implemented, and you need to rewrite the code? You would be rewriting in many applications, which could lead to a nighmare.

So, the point is to create something that can be reused any time. This is whay ProcessCmdKey should be used for. And this is where you should have implemented the cell focus behavior, but, in this case, ONLY that. You should not place any custom validation code in it.

Back to the problem. Altough I havent tested thoroughly SendKeys with CellValidating, I did experience what you were saying only if a breakpoint is set. Therefore it should be ok in the release code. Anyway, it is not the best solution, I agree, but its better that doing this in ProcessCmdKey event.

Remove the cell value valdation from CellValueChanged, and from ProcessCmdKey. We will use EditingControlShowing event to prevent user to type anything but numeric values. If you need to use decimal values, then you should also allow dot (.), but before you do, check if there is one already (dont allow two dots).


    Dim textBoxHandlerAdded As Boolean
 
    Private Sub DataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
 
        If Not TypeOf e.Control Is TextBox Then Exit Sub
 
        If Not handlerAdded Then
            AddHandler CType(e.Control, TextBox).KeyPress, AddressOf ValidateInput
            handlerAdded = True
        End If
    End Sub
 
    Private Sub ValidateInput(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs)
        Select Case Asc(e.KeyChar)
            Case 8, 48 To 57
            Case Else
                e.KeyChar = Nothing
        End Select
    End Sub

Open in new window

0
 
LVL 1

Author Comment

by:emi_sastra
ID: 23061992
Hi Priest04,

I am sorry, just back again.

It works, but need additional code to check certain cells is in editing and decimal symbol.

Thank you.
0
 
LVL 18

Expert Comment

by:Priest04
ID: 23062718
>>It works, but need additional code to check certain cells is in editing

Do you mean you want to check that cell in certain column is editing? Here is improved version that handles this and decimal point.

Private Sub ValidateInput(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs)
    If  e.ColumnIndex = EnumGridViewColumn.NilaiTransaksi Or e.ColumnIndex = EnumGridViewColumn.NilaiKurs Then
        Select Case Asc(e.KeyChar)
            Case 8, 48 To 57 ' delete key and numeric keys
                ' do nothing
            Case 46 ' decimal point
                ' ckeck if there is another one
                If TextBox1.Text.IndexOf(e.KeyChar) <> -1 Then
                    e.KeyChar = Nothing
                End If
            Case Else
                e.KeyChar = Nothing
        End Select
    end if
End Sub
0
 
LVL 1

Author Comment

by:emi_sastra
ID: 23065816
There is one problem, when I click one of the cells then the handler still active.

  If  e.ColumnIndex = EnumGridViewColumn.NilaiTransaksi Or e.ColumnIndex = EnumGridViewColumn.NilaiKurs Then

The above code has limitation, we have to check the column, how about checking if it is numeric column type?

Thank you.
0
 
LVL 18

Expert Comment

by:Priest04
ID: 23067159
Pardon, my mistake. It should have been

If dgvTransaksi.CurrentCell.ColumnIndex = EnumGridViewColumn.NilaiTransaksi Or dgvTransaksi.CurrentCell.ColumnIndex = EnumGridViewColumn.NilaiKurs Then

0
 
LVL 1

Author Comment

by:emi_sastra
ID: 23070550
Still have problem.

 If Not handlerAdded Then
            AddHandler CType(e.Control, TextBox).KeyPress, AddressOf ValidateInput
            handlerAdded = True
        End If

This handler always active at any cell? Its mean when the current is not EnumGridViewColumn.NilaiTransaksi and EnumGridViewColumn.NilaiKurs  then non numeric input will be reject.

Could we just check the cell type? if it is numeric than we do the addhandler.

Thank you.
0
 
LVL 18

Expert Comment

by:Priest04
ID: 23070808
When you add handler for any cell any any column, you have added it for all. I do not understand your questions. What is the problem if handler is active? There is not such thing as numeric cell type,  there are types like Int16, Int32, Int64, UInt16, UInt32, UInt64, float, double, etc, so you would need to check for every type that can accept numeric values, or if you use only one or two types, then you can check only them.

To check the type of the cell

If dgvTransaksi.CurrentCell.ValueType Is GetType(Double) Then

End If

But I dont see why dont you check the column index? Its much easier, and much more cleaner.

Private Sub ValidateInput(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs)
    ' this will be fired on ANY cell edit
    If  e.ColumnIndex = EnumGridViewColumn.NilaiTransaksi Or e.ColumnIndex = EnumGridViewColumn.NilaiKurs Then
        ' but this code will be executed only for NilaiTransaksi and NilaiKurs columns
        Select Case Asc(e.KeyChar)
0
 
LVL 1

Author Comment

by:emi_sastra
ID: 23070890
When you add handler for any cell any any column, you have added it for all.
That's the problem.

When the column is not NilaiTransaksi and NilaiKurs then it will not accept numeric key, right? It will return nothing.

 Private Sub ValidateInput(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs)
        Select Case Asc(e.KeyChar)
            Case 8, 48 To 57
            Case Else
                e.KeyChar = Nothing
        End Select
    End Sub


Thank you.
0
 
LVL 18

Expert Comment

by:Priest04
ID: 23071027
emi_sastra, seems to me I am posting here code for nothing, since you are not looking at it?

Looak at the post dated 11.30.2008 at 12:33PM CET
0
 
LVL 1

Author Comment

by:emi_sastra
ID: 23071189
Do you mean below code?

Private Sub ValidateInput(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs)
    If  e.ColumnIndex = EnumGridViewColumn.NilaiTransaksi Or e.ColumnIndex = EnumGridViewColumn.NilaiKurs Then
        Select Case Asc(e.KeyChar)
            Case 8, 48 To 57 ' delete key and numeric keys
                ' do nothing
            Case 46 ' decimal point
                ' ckeck if there is another one
                If TextBox1.Text.IndexOf(e.KeyChar) <> -1 Then
                    e.KeyChar = Nothing
                End If
            Case Else
                e.KeyChar = Nothing
        End Select
    end if
End Sub

If you mean this, this is not the problem.

Your forgot to remove handler when it is not needed, am I right?

 Private Sub dgvTransaksi_EditingControlShowing(ByVal sender As Object, ByVal e As DataGridViewEditingControlShowingEventArgs) Handles dgvTransaksi.EditingControlShowing

        If Not TypeOf e.Control Is TextBox Then Exit Sub

        Dim dgv As DataGridView = sender

        With dgv

            If .Columns(.CurrentCell.ColumnIndex).ValueType.ToString = GetType(Decimal).ToString Then

                If Not blnHandlerAdded Then
                    AddHandler CType(e.Control, TextBox).KeyPress, AddressOf ERV_Global.ValidateNumericInput
                    blnHandlerAdded = True
                End If

            Else

               'This is where you forgot
                RemoveHandler CType(e.Control, TextBox).KeyPress, AddressOf ERV_Global.ValidateNumericInput
                blnHandlerAdded = False
            End If

        End With

    End Sub

Thank you.


0
 
LVL 18

Expert Comment

by:Priest04
ID: 23071306
No, I didnt. As I sad, it doesnt make any difference. This way you are only adding/removing hanlders, anytime you change column (from decimal type to non-decimal).

As I said, quite unnecessary.
0
 
LVL 1

Author Comment

by:emi_sastra
ID: 23071382
Please see the scenario.

Let's say we have 3 colums.

1. ItemCode
2. ItemName
3. ItemQty

Let's say we have move to ItemQty column and the handler is active, which mean we can not input anything excep number and decimalk symbol.

Now, we click ItemCode cell which should could accept number and non number key. Since the handler still active then we can not input non number key, am I right? Therefore when the current cell is not number field then we should deactivate the handler, am I right?

Thank you.
0
 
LVL 18

Expert Comment

by:Priest04
ID: 23071564
If you used this code

Private Sub ValidateInput(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs)
        Select Case Asc(e.KeyChar)
            Case 8, 48 To 57
            Case Else
                e.KeyChar = Nothing
        End Select
    End Sub


Then you are incorrect. However, this is why you should add column index validation, so it will validate only 2nd and 3rd column. In your example, if column index for ItemCode  is 0, so it will not validate it.

Private Sub ValidateInput(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs)
    If  dgvTransaksi.CurrectCell.ColumnIndex = 1 or dgvTransaksi.CurrectCell.ColumnIndex = 2 Then
        Select Case Asc(e.KeyChar)
            Case 8, 48 To 57 ' delete key and numeric keys
                ' do nothing
            Case 46 ' decimal point
                ' ckeck if there is another one
                If TextBox1.Text.IndexOf(e.KeyChar) <> -1 Then
                    e.KeyChar = Nothing
                End If
            Case Else
                e.KeyChar = Nothing
        End Select
    end if
End Sub

What I used in my code are enum values, which I saw you were using in your example, so NilaiTransaksi should have value 1 and NilaiKurs should have value 2. If this enums should not be applied in this example, then you should replace it with the accoring ones, I cannot know the structure of your project.

If  dgvTransaksi.CurrectCell.ColumnIndex = EnumGridViewColumn.NilaiTransaksi Or dgvTransaksi.CurrectCell.ColumnIndex = EnumGridViewColumn.NilaiKurs Then

0
 
LVL 18

Expert Comment

by:Priest04
ID: 23071586
pardon I made a typing mistake. I wrote

>>Then you are incorrect. However, this is why you should add column index validation,

should have been

Then you are correct. However, this is why you should add column index validation,
0
 
LVL 1

Author Comment

by:emi_sastra
ID: 23071744
Ok.

If  dgvTransaksi.CurrectCell.ColumnIndex = 1 or dgvTransaksi.CurrectCell.ColumnIndex = 2 Then

If we use the above code then it will be the code at any form. I want to make it public so we don't have to take care the column number.

Thus my code like below:

 Public Shared Sub ValidateNumericInput(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs)
        Select Case Asc(e.KeyChar)
            Case 8, 48 To 57
            Case Asc(Get_Decimal_Char())
                'If TextBox1.Text.IndexOf(e.KeyChar) <> -1 Then
                '    e.KeyChar = Nothing
                'End If
            Case Else
                e.KeyChar = Nothing
        End Select
    End Sub

Then I should removehandler if I use the above code.

How to make the remarks line working?

Thank you.
0
 
LVL 18

Expert Comment

by:Priest04
ID: 23071978
If you want to make it public, then the only way is to add/remove handlers.

What do you mean by "make the remark working"? I thought that all issues are solved
0
 
LVL 18

Expert Comment

by:Priest04
ID: 23071990
Aha, got it. :)


If ((sender)TextBox).Text.IndexOf(e.KeyChar) <> -1 Then
    e.KeyChar = Nothing
End If

Open in new window

0
 
LVL 18

Expert Comment

by:Priest04
ID: 23072074
well, its a c# mixed code, I am currently coding in c#. VB.NET casting is done with CType, if I remember well


If CType(sender, TextBox).Text.IndexOf(e.KeyChar) <> -1 Then
    e.KeyChar = Nothing
End If

Open in new window

0
 
LVL 1

Author Comment

by:emi_sastra
ID: 23072112
Hi  Priest04,

It works. Just for your info, below code will handle decimal for any regional setting.

Public Shared Function Get_Decimal_Char() As String
        Dim curNilai As Decimal
        curNilai = 1.5

        Get_Decimal_Char = Format(curNilai, "#.0")
        Get_Decimal_Char = Mid(Get_Decimal_Char, 2, 1)
    End Function

Thank you very much for your help.
0
 
LVL 18

Expert Comment

by:Priest04
ID: 23072187
You are welcome. There is a built in method that will return decimal sign from the number, I think in CurrentUICulture class, if my memory server me well.
0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

1.0 - Introduction Converting Visual Basic 6.0 (VB6) to Visual Basic 2008+ (VB.NET). If ever there was a subject full of murkiness and bad decisions, it is this one!   The first problem seems to be that people considering this task of converting…
Microsoft Reports are based on a report definition, which is an XML file that describes data and layout for the report, with a different extension. You can create a client-side report definition language (*.rdlc) file with Visual Studio, and build g…
Look below the covers at a subform control , and the form that is inside it. Explore properties and see how easy it is to aggregate, get statistics, and synchronize results for your data. A Microsoft Access subform is used to show relevant calcul…
Whether it be Exchange Server Crash Issues, Dirty Shutdown Errors or Failed to mount error, Stellar Phoenix Mailbox Exchange Recovery has always got your back. With the help of its easy to understand user interface and 3 simple steps recovery proced…
Suggested Courses

830 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question