emi_sastra
asked on
Error handling in datagridview cell editing.
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.
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.
ASKER
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.
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.
Try doing the checking in the RowUpdating event
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
ASKER
Hi M3mph15,
How to check it?
Thank you.
How to check it?
Thank you.
ASKER
Hi jpaulino,
How to check if the problem is on certain column?
Thank you.
How to check if the problem is on certain column?
Thank you.
ASKER
Hi jpaulino,
i use ProcessCmdKey.
Case EnumGridViewColumn.NilaiTr ansaksi
If Not IsNumeric(dgvRow.Cells(.Cu rrentCell. ColumnInde x).Value) Then
dgvRow.Cells(.CurrentCell. ColumnInde x).Value = 0
End If
If dgvRow.Cells(.CurrentCell. ColumnInde x).Value < 0 Then
dgvRow.Cells(.CurrentCell. ColumnInde x).Value = 0
End If
If dgvRow.Cells("Keterangan") .Value.ToS tring.Trim = "" Then
dgvRow.Cells("NilaiKurs"). Value = CDbl(txtNilaiKurs.Text)
End If
'Exception at below code
.CurrentCell = .Rows(.CurrentCell.RowInde x).Cells(. CurrentCel l.ColumnIn dex + 1)
Thank you.
i use ProcessCmdKey.
Case EnumGridViewColumn.NilaiTr
If Not IsNumeric(dgvRow.Cells(.Cu
dgvRow.Cells(.CurrentCell.
End If
If dgvRow.Cells(.CurrentCell.
dgvRow.Cells(.CurrentCell.
End If
If dgvRow.Cells("Keterangan")
dgvRow.Cells("NilaiKurs").
End If
'Exception at below code
.CurrentCell = .Rows(.CurrentCell.RowInde
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
>> 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 ?
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 ?
ASKER
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.RowInde x).Cells(. CurrentCel l.ColumnIn dex + 1)
The code above is inside ProcessCmdKey procedure.
Thank you.
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.RowInde
The code above is inside ProcessCmdKey procedure.
Thank you.
>> 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
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
ASKER
You should change to the column where you want to validate.
Yes, that's why I change to :
Private Sub dgvTransaksi_CellEndEdit(B yVal sender As Object, ByVal e As System.Windows.Forms.DataG ridViewCel lEventArgs ) 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.dgvTra nsaksi(e.C olumnIndex , e.RowIndex).Value.ToString , result) Then
If e.ColumnIndex = EnumGridViewColumn.NilaiTr ansaksi Or _
e.ColumnIndex = EnumGridViewColumn.NilaiKu rs Then
Me.dgvTransaksi(e.ColumnIn dex, 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.
Yes, that's why I change to :
Private Sub dgvTransaksi_CellEndEdit(B
' 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.dgvTra
If e.ColumnIndex = EnumGridViewColumn.NilaiTr
e.ColumnIndex = EnumGridViewColumn.NilaiKu
Me.dgvTransaksi(e.ColumnIn
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
>> 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.
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.
ASKER
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.RowInde x).Cells(. CurrentCel l.ColumnIn dex + 1)
Thank you.
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.RowInde
Thank you.
>> 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
ASKER
I change to :
If e.ColumnIndex = EnumGridViewColumn.NilaiTr ansaksi Or _
e.ColumnIndex = EnumGridViewColumn.NilaiKu rs Then
Dim result As Integer
If Not Integer.TryParse(Me.dgvTra nsaksi(e.C olumnIndex , e.RowIndex).Value.ToString , result) Then
Me.dgvTransaksi(e.ColumnIn dex, e.RowIndex).Value = 0
End If
End If
The error still happens.
Thank you.
If e.ColumnIndex = EnumGridViewColumn.NilaiTr
e.ColumnIndex = EnumGridViewColumn.NilaiKu
Dim result As Integer
If Not Integer.TryParse(Me.dgvTra
Me.dgvTransaksi(e.ColumnIn
End If
End If
The error still happens.
Thank you.
>> The error still happens.
What errors ?
What errors ?
ASKER
Operation did not succeed because the program cannot commit or quit a cell value change.
Exception happened inside ProcessCmdKey under code :
.CurrentCell = .Rows(.CurrentCell.RowInde x).Cells(. CurrentCel l.ColumnIn dex + 1)
Thank you.
Exception happened inside ProcessCmdKey under code :
.CurrentCell = .Rows(.CurrentCell.RowInde
Thank you.
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
ASKER
Hi Priest04,
Still get the same error.
Thank you.
Still get the same error.
Thank you.
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.
ASKER
Do you use below ProcessCmdKey in you code?
Thank you.
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
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.
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.
ASKER
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.RowInde x).Cells(. CurrentCel l.ColumnIn dex + 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(ByV al sender As Object, ByVal e As System.Windows.Forms.DataG ridViewDat aErrorEven tArgs) 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.ColumnIn dex, e.RowIndex).Value = 0.
Thank you.
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.RowInde
The code you provide has 2 problem:
1. I have to add event below, otherwise will cause error.
Private Sub dgvTransaksi_DataError(ByV
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.ColumnIn
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
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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.
I am sorry, just back again.
It works, but need additional code to check certain cells is in editing and decimal symbol.
Thank you.
>>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.KeyPr essEventAr gs)
If e.ColumnIndex = EnumGridViewColumn.NilaiTr ansaksi Or e.ColumnIndex = EnumGridViewColumn.NilaiKu rs 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.Ke yChar) <> -1 Then
e.KeyChar = Nothing
End If
Case Else
e.KeyChar = Nothing
End Select
end if
End Sub
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.KeyPr
If e.ColumnIndex = EnumGridViewColumn.NilaiTr
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.Ke
e.KeyChar = Nothing
End If
Case Else
e.KeyChar = Nothing
End Select
end if
End Sub
ASKER
There is one problem, when I click one of the cells then the handler still active.
If e.ColumnIndex = EnumGridViewColumn.NilaiTr ansaksi Or e.ColumnIndex = EnumGridViewColumn.NilaiKu rs Then
The above code has limitation, we have to check the column, how about checking if it is numeric column type?
Thank you.
If e.ColumnIndex = EnumGridViewColumn.NilaiTr
The above code has limitation, we have to check the column, how about checking if it is numeric column type?
Thank you.
Pardon, my mistake. It should have been
If dgvTransaksi.CurrentCell.C olumnIndex = EnumGridViewColumn.NilaiTr ansaksi Or dgvTransaksi.CurrentCell.C olumnIndex = EnumGridViewColumn.NilaiKu rs Then
If dgvTransaksi.CurrentCell.C
ASKER
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.NilaiTr ansaksi and EnumGridViewColumn.NilaiKu rs 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.
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.NilaiTr
Could we just check the cell type? if it is numeric than we do the addhandler.
Thank you.
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.V alueType 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.KeyPr essEventAr gs)
' this will be fired on ANY cell edit
If e.ColumnIndex = EnumGridViewColumn.NilaiTr ansaksi Or e.ColumnIndex = EnumGridViewColumn.NilaiKu rs Then
' but this code will be executed only for NilaiTransaksi and NilaiKurs columns
Select Case Asc(e.KeyChar)
To check the type of the cell
If dgvTransaksi.CurrentCell.V
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.KeyPr
' this will be fired on ANY cell edit
If e.ColumnIndex = EnumGridViewColumn.NilaiTr
' but this code will be executed only for NilaiTransaksi and NilaiKurs columns
Select Case Asc(e.KeyChar)
ASKER
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.KeyPr essEventAr gs)
Select Case Asc(e.KeyChar)
Case 8, 48 To 57
Case Else
e.KeyChar = Nothing
End Select
End Sub
Thank you.
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.KeyPr
Select Case Asc(e.KeyChar)
Case 8, 48 To 57
Case Else
e.KeyChar = Nothing
End Select
End Sub
Thank you.
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
Looak at the post dated 11.30.2008 at 12:33PM CET
ASKER
Do you mean below code?
Private Sub ValidateInput(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPr essEventAr gs)
If e.ColumnIndex = EnumGridViewColumn.NilaiTr ansaksi Or e.ColumnIndex = EnumGridViewColumn.NilaiKu rs 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.Ke yChar) <> -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_EditingContro lShowing(B yVal sender As Object, ByVal e As DataGridViewEditingControl ShowingEve ntArgs) Handles dgvTransaksi.EditingContro lShowing
If Not TypeOf e.Control Is TextBox Then Exit Sub
Dim dgv As DataGridView = sender
With dgv
If .Columns(.CurrentCell.Colu mnIndex).V alueType.T oString = GetType(Decimal).ToString Then
If Not blnHandlerAdded Then
AddHandler CType(e.Control, TextBox).KeyPress, AddressOf ERV_Global.ValidateNumeric Input
blnHandlerAdded = True
End If
Else
'This is where you forgot
RemoveHandler CType(e.Control, TextBox).KeyPress, AddressOf ERV_Global.ValidateNumeric Input
blnHandlerAdded = False
End If
End With
End Sub
Thank you.
Private Sub ValidateInput(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPr
If e.ColumnIndex = EnumGridViewColumn.NilaiTr
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.Ke
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_EditingContro
If Not TypeOf e.Control Is TextBox Then Exit Sub
Dim dgv As DataGridView = sender
With dgv
If .Columns(.CurrentCell.Colu
If Not blnHandlerAdded Then
AddHandler CType(e.Control, TextBox).KeyPress, AddressOf ERV_Global.ValidateNumeric
blnHandlerAdded = True
End If
Else
'This is where you forgot
RemoveHandler CType(e.Control, TextBox).KeyPress, AddressOf ERV_Global.ValidateNumeric
blnHandlerAdded = False
End If
End With
End Sub
Thank you.
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.
As I said, quite unnecessary.
ASKER
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.
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.
If you used this code
Private Sub ValidateInput(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPr essEventAr gs)
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.KeyPr essEventAr gs)
If dgvTransaksi.CurrectCell.C olumnIndex = 1 or dgvTransaksi.CurrectCell.C olumnIndex = 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.Ke yChar) <> -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.C olumnIndex = EnumGridViewColumn.NilaiTr ansaksi Or dgvTransaksi.CurrectCell.C olumnIndex = EnumGridViewColumn.NilaiKu rs Then
Private Sub ValidateInput(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPr
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.KeyPr
If dgvTransaksi.CurrectCell.C
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.Ke
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.C
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,
>>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,
ASKER
Ok.
If dgvTransaksi.CurrectCell.C olumnIndex = 1 or dgvTransaksi.CurrectCell.C olumnIndex = 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.KeyPr essEventAr gs)
Select Case Asc(e.KeyChar)
Case 8, 48 To 57
Case Asc(Get_Decimal_Char())
'If TextBox1.Text.IndexOf(e.Ke yChar) <> -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.
If dgvTransaksi.CurrectCell.C
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
Select Case Asc(e.KeyChar)
Case 8, 48 To 57
Case Asc(Get_Decimal_Char())
'If TextBox1.Text.IndexOf(e.Ke
' 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.
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
What do you mean by "make the remark working"? I thought that all issues are solved
Aha, got it. :)
If ((sender)TextBox).Text.IndexOf(e.KeyChar) <> -1 Then
e.KeyChar = Nothing
End If
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
ASKER
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.
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.
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.
GridView1.Rows([rowindex])
End If