BlakeMcKenna
asked on
What is the best DataGridView Event to process Cell activity?
I have a DataGridView that requires User input in a couple of Cells. There seems to be quite a few Cell Events available and I just want to use the right one.
The scenario for this functionality is that the cursor will be placed in a cell awaiting for the User to press/click the Enter Key. At this point, a reading from a PLC will be taken and the value inserted into the Cell. The User also has the option to manually change this reading within the Cell.
With this said, I'm sure there will be more than one Event used. I just want to make sure I'm using the correct ones.
Thanks!
The scenario for this functionality is that the cursor will be placed in a cell awaiting for the User to press/click the Enter Key. At this point, a reading from a PLC will be taken and the value inserted into the Cell. The User also has the option to manually change this reading within the Cell.
With this said, I'm sure there will be more than one Event used. I just want to make sure I'm using the correct ones.
Thanks!
I am not quite sure that I understand the events that you will need. It sounds like you don't need any events with the scenario described.
ASKER
My apologies...your right. Once a value is received, calculations are performed. I also failed to mention that the User also has the ability to manually override the value that was received into the cell with NUMERIC data only.
Once the cell has an accepted value, calculations are made using this value. Hope that helps!
Thanks!
Once the cell has an accepted value, calculations are made using this value. Hope that helps!
Thanks!
ASKER
Does anyone have an answer to this question?
Hmmm...I don't remember seeing any E-Mail for this question. What events have you tried, and what indications are you getting? The DataGridView control is very buggy, and very difficult to work with when it comes to some types of requirements.
ASKER
Here is the easiest way for me to explain the problem I'm having. Please take a look at the screen shot.
Editable Columns include "Rin" thru "Final Zero".
Editable Columns allow for a User to manually enter numeric data ONLY...or they simply hit the Enter/Return Key and the application retrieves a decimal value from an Electronic MultiMeter Device. Once the value is retrieved, it needs to advance the cursor to the next COLUMN rather than the next row. The exception to this is when the cursor is in the last Editable Column, at which point it needs to advance to the next ROW and be in the "Rin" column.
I'm thinking this should be fairly simple to accomplish but due to my lack of knowledge with the functionality of the DGV, I'm afraid I've made a "mountain out of a mole hill".
Please help as I am coming down to a deadline.
Thanks!
Screentshot.jpg
Editable Columns include "Rin" thru "Final Zero".
Editable Columns allow for a User to manually enter numeric data ONLY...or they simply hit the Enter/Return Key and the application retrieves a decimal value from an Electronic MultiMeter Device. Once the value is retrieved, it needs to advance the cursor to the next COLUMN rather than the next row. The exception to this is when the cursor is in the last Editable Column, at which point it needs to advance to the next ROW and be in the "Rin" column.
I'm thinking this should be fairly simple to accomplish but due to my lack of knowledge with the functionality of the DGV, I'm afraid I've made a "mountain out of a mole hill".
Please help as I am coming down to a deadline.
Thanks!
Screentshot.jpg
Let's try something here--let's add a custom DataGridView that overrides the OnKeyDown method:
Imports System.ComponentModel
Imports System.Windows.Forms
Namespace Sample
Public Enum EnterBehavior
NextRow
NextColumn
End Enum
''' <summary>
''' A DataGridView with a StandardEnter property which behaves
''' like StandardTab.
''' </summary>
Public Class StandardEnterDataGridView
Inherits DataGridView
''' <summary>
''' Sets the behavior for the {Enter} key. Either next row (default),
''' or next column.
''' </summary>
<Category("Behavior"), Description("Disable default edit/advance to next row behavior of of the Enter key.")> _
Public Property EnterKeyBehavior() As EnterBehavior
Get
Return m_EnterKeyBehavior
End Get
Set
m_EnterKeyBehavior = Value
End Set
End Property
Private m_EnterKeyBehavior As EnterBehavior
Protected Overrides Sub OnKeyDown(e As KeyEventArgs)
If EnterKeyBehavior = EnterBehavior.NextColumn AndAlso e.KeyCode = Keys.Enter Then
e = New KeyEventArgs(Keys.Tab)
End If
MyBase.OnKeyDown(e)
End Sub
End Class
End Namespace
ASKER
I know this is a dumb question but Do I need to create a new Class Module or can I just add this to my Form Class? I'm not real good with inheritance. How do I implement this?
The difference between overriding the default behavior of the DataGridView, and using an event handler is the amount of control.
For an event handler, you would attach to the KeyPress event handler, check for an {Enter} key, and set event arguments "e.Handled = true", and then use SendKeys.Send with a {Tab} key.
If you can't translate that description to code, I will help you, but I would like to see you try first.
For an event handler, you would attach to the KeyPress event handler, check for an {Enter} key, and set event arguments "e.Handled = true", and then use SendKeys.Send with a {Tab} key.
If you can't translate that description to code, I will help you, but I would like to see you try first.
ASKER
Ok, but am I using the same code that is in the KeyDown Event or do I need to recode from scratch? I do want to learn this but I'm really under a time constraint.
Time pressures are part of the job...
It's pretty simple, once you get the hang of it:
It's pretty simple, once you get the hang of it:
Private Sub DataGridView1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles DataGridView1.KeyPress
If e.KeyChar = Chr(13) Then
e.Handled = True
SendKeys.Send("{TAB}")
End If
End Sub
ASKER
Ok, I tried the above code snippet and the cursor advances horizontally, however, it skips a cell in the process.
If you comment out the SendKeys call, does it still move the current cell? If so, then we need to find out what causes that behavior, and stop it from happening.
ASKER
I commented out the SendKey Call and it advanced the cursor 1 row down and 1 column to the right. Here is the code that I'm using and I'm sure it's overkill but it's what this mind of mine thinks. Any reference to the variable "blnOEM" is always true for now.
Private Sub dgvLoadTests_CellEndEdit(s ender As Object, e As DataGridViewCellEventArgs) Handles dgvLoadTests.CellEndEdit
Try
EH.strRetVal = ""
If blnOEM Then
If colIDX < dgvLoadTests.Columns.Count - 3 Then
dgvLoadTests.CurrentCell = dgvLoadTests(colIDX + 1, rowIDX)
Else
If rowIDX = dgvLoadTests.Rows.Count - 1 Then
dgvLoadTests.CurrentCell = dgvLoadTests(colIDX, rowIDX)
Else
dgvLoadTests.CurrentCell = dgvLoadTests(2, rowIDX + 1)
End If
End If
Else
If rowIDX < dgvLoadTests.Rows.Count - 1 Then
dgvLoadTests.CurrentCell = dgvLoadTests(colIDX, rowIDX + 1)
Else
dgvLoadTests.CurrentCell = dgvLoadTests(colIDX, rowIDX)
End If
End If
Catch ex As Exception
EH.strRetVal = gfrmID & "/dgvLoadTests_CellEndEdit () - " & ex.Message
End Try
EH.ProcessMessages(Me, sbr, EH.strRetVal)
End Sub
'
'
'
Private Sub dgvLoadTests_CellMouseClic k(sender As Object, e As DataGridViewCellMouseEvent Args) Handles dgvLoadTests.CellMouseClic k
Try
iRow = dgvLoadTests.CurrentRow.In dex
EH.strRetVal = ""
Catch ex As Exception
EH.strRetVal = gfrmID & "/dgvLoadTests_CellMouseCl ick() - " & ex.Message
End Try
EH.ProcessMessages(Me, sbr, EH.strRetVal)
End Sub
'
'
'
Private Sub dgvLoadTests_CellValidatin g(sender As Object, e As DataGridViewCellValidating EventArgs) Handles dgvLoadTests.CellValidatin g
Try
EH.strRetVal = ""
rowIDX = dgvLoadTests.CurrentCellAd dress.Y 'Get Row Index
colIDX = dgvLoadTests.CurrentCellAd dress.X 'Get Column Index
If dgvLoadTests.Item(e.Column Index, e.RowIndex).IsInEditMode Then
If Not dgvLoadTests.Item(e.Column Index, e.RowIndex).ValueType Is GetType(Decimal) Then
Dim c As Control = dgvLoadTests.EditingContro l
Dim cell As DataGridViewCell = dgvLoadTests.CurrentCell
If Not Decimal.TryParse(c.Text, Nothing) Then
If c.Text = "" Then
Else
EH.strRetVal = "Invalid Numeric Value!" & "~I"
e.Cancel = True
End If
Else
If blnOEM Then
Select Case e.RowIndex
Case 0
cell.Value = Format(c.Text, c.Text) 'Don't format the Load Values
Case Else
cell.Value = Format(c.Text, GetDecimalPlaces(c.Text))
End Select
Else
Select Case e.ColumnIndex
Case 1
cell.Value = Format(c.Text, c.Text) 'Don't format the Load Values
Case Else
cell.Value = Format(c.Text, GetDecimalPlaces(c.Text))
End Select
End If
End If
dgvLoadTests.CancelEdit()
End If
End If
Catch ex As Exception
EH.strRetVal = gfrmID & "/dgvLoadTests_CellValidat ing() - " & ex.Message
End Try
EH.ProcessMessages(Me, sbr, EH.strRetVal)
End Sub
'
'
'
Private Sub dgvLoadTests_KeyDown(sende r As Object, e As KeyEventArgs) Handles dgvLoadTests.KeyDown
Try
EH.strRetVal = ""
nonNumbered = False
Select Case e.KeyCode
Case Keys.Enter Or Keys.Return
rowIDX = dgvLoadTests.CurrentCellAd dress.Y 'Get Row Index
colIDX = dgvLoadTests.CurrentCellAd dress.X 'Get Column Index
If blnOEM Then
Select Case colIDX
Case 0 To 1 'Columns 0 & 1
Case dgvLoadTests.Columns.Count - 2 'The last editable column
If rowIDX < dgvLoadTests.Rows.Count - 1 Then 'This is any row other than the last row in the Grid
dgvLoadTests.CurrentCell = dgvLoadTests(2, rowIDX + 1)
Else
dgvLoadTests.Rows(rowIDX). Cells(colI DX).Value = GetDecimalPlaces("00.0000" ) 'Get Multimeter Reading
End If
Case Else
If rowIDX = dgvLoadTests.Rows.Count - 1 Then 'This is the last row
If Not colIDX = dgvLoadTests.Columns.Count - 3 Then 'This is the last editable column
dgvLoadTests.CurrentCell = dgvLoadTests(colIDX + 1, rowIDX)
End If
dgvLoadTests.Rows(rowIDX). Cells(colI DX).Value = GetDecimalPlaces("00.0000" ) 'Get Multimeter Reading
Else
If colIDX >= 2 And colIDX < dgvLoadTests.Columns.Count - 3 Then
dgvLoadTests.CurrentCell = dgvLoadTests(colIDX + 1, rowIDX)
dgvLoadTests.Rows(rowIDX). Cells(colI DX).Value = GetDecimalPlaces("00.0000" ) 'Get Multimeter Reading
ElseIf colIDX = dgvLoadTests.Columns.Count - 3 Then
dgvLoadTests.CurrentCell = dgvLoadTests(2, rowIDX + 1)
dgvLoadTests.Rows(rowIDX). Cells(colI DX).Value = GetDecimalPlaces("00.0000" ) 'Get Multimeter Reading
Else
dgvLoadTests.CurrentCell = dgvLoadTests(colIDX + 1, rowIDX)
dgvLoadTests.Rows(rowIDX). Cells(colI DX).Value = GetDecimalPlaces("00.0000" ) 'Get Multimeter Reading
End If
End If
End Select
Else 'Take this branch for Non-OEM Tests (a single Sensor test)
Select Case rowIDX
Case 0
If colIDX = 1 Then
dgvLoadTests.Rows(rowIDX). Cells(colI DX).Value = GetDecimalPlaces("00.0000" ) 'Get Multimeter Reading
End If
Case dgvLoadTests.Rows.Count - 1 'TEST IS FINISHED at this point
'dgvLoadTests.Rows(rowIDX) .Cells(col IDX).Value = GetDecimalPlaces("00.0000" ) 'Get Multimeter Reading
Case Else
dgvLoadTests.Rows(rowIDX). Cells(colI DX).Value = GetDecimalPlaces("00.0000" ) 'Get Multimeter Reading
End Select
End If
Case Keys.D0 To Keys.D9
Case Keys.NumPad0 To Keys.NumPad9
Case Keys.Delete
nonNumbered = False
dgvLoadTests.Rows(rowIDX). Cells(colI DX).Value = ""
Case Keys.Back
Case Else
nonNumbered = True
End Select
Catch ex As Exception
EH.strRetVal = gfrmID & "/dgvLoadTests_KeyDown() - " & ex.Message
End Try
EH.ProcessMessages(Me, sbr, EH.strRetVal)
End Sub
'
'
'
Private Sub dgvLoadTests_KeyPress(send er As Object, e As KeyPressEventArgs) Handles dgvLoadTests.KeyPress
Try
rowIDX = dgvLoadTests.CurrentCell.R owIndex
colIDX = dgvLoadTests.CurrentCell.C olumnIndex
If e.KeyChar = Chr(13) Then
e.Handled = True
'SendKeys.Send("{TAB}")
If rowIDX = dgvLoadTests.Rows.Count - 1 Then
Else
End If
End If
EH.strRetVal = ""
Catch ex As Exception
EH.strRetVal = gfrmID & "/dgvLoadTests_KeyPress() - " & ex.Message
End Try
EH.ProcessMessages(Me, sbr, EH.strRetVal)
End Sub
'
'
'
Private Sub dgvLoadTests_MouseClick(se nder As Object, e As MouseEventArgs) Handles dgvLoadTests.MouseClick
Try
EH.strRetVal = ""
If Not blnManual Then
Dim col As Integer = dgvLoadTests.CurrentCell.C olumnIndex
If col = 5 Then
SetMatrix(Me.Name, cmbOutputUnit.Text, FaultyDeviceName)
End If
End If
Catch ex As Exception
EH.strRetVal = gfrmID & "/dgvLoadTests_MouseClick( ) - " & ex.Message
End Try
EH.ProcessMessages(Me, sbr, EH.strRetVal)
End Sub
Private Sub dgvLoadTests_CellEndEdit(s
Try
EH.strRetVal = ""
If blnOEM Then
If colIDX < dgvLoadTests.Columns.Count
dgvLoadTests.CurrentCell = dgvLoadTests(colIDX + 1, rowIDX)
Else
If rowIDX = dgvLoadTests.Rows.Count - 1 Then
dgvLoadTests.CurrentCell = dgvLoadTests(colIDX, rowIDX)
Else
dgvLoadTests.CurrentCell = dgvLoadTests(2, rowIDX + 1)
End If
End If
Else
If rowIDX < dgvLoadTests.Rows.Count - 1 Then
dgvLoadTests.CurrentCell = dgvLoadTests(colIDX, rowIDX + 1)
Else
dgvLoadTests.CurrentCell = dgvLoadTests(colIDX, rowIDX)
End If
End If
Catch ex As Exception
EH.strRetVal = gfrmID & "/dgvLoadTests_CellEndEdit
End Try
EH.ProcessMessages(Me, sbr, EH.strRetVal)
End Sub
'
'
'
Private Sub dgvLoadTests_CellMouseClic
Try
iRow = dgvLoadTests.CurrentRow.In
EH.strRetVal = ""
Catch ex As Exception
EH.strRetVal = gfrmID & "/dgvLoadTests_CellMouseCl
End Try
EH.ProcessMessages(Me, sbr, EH.strRetVal)
End Sub
'
'
'
Private Sub dgvLoadTests_CellValidatin
Try
EH.strRetVal = ""
rowIDX = dgvLoadTests.CurrentCellAd
colIDX = dgvLoadTests.CurrentCellAd
If dgvLoadTests.Item(e.Column
If Not dgvLoadTests.Item(e.Column
Dim c As Control = dgvLoadTests.EditingContro
Dim cell As DataGridViewCell = dgvLoadTests.CurrentCell
If Not Decimal.TryParse(c.Text, Nothing) Then
If c.Text = "" Then
Else
EH.strRetVal = "Invalid Numeric Value!" & "~I"
e.Cancel = True
End If
Else
If blnOEM Then
Select Case e.RowIndex
Case 0
cell.Value = Format(c.Text, c.Text) 'Don't format the Load Values
Case Else
cell.Value = Format(c.Text, GetDecimalPlaces(c.Text))
End Select
Else
Select Case e.ColumnIndex
Case 1
cell.Value = Format(c.Text, c.Text) 'Don't format the Load Values
Case Else
cell.Value = Format(c.Text, GetDecimalPlaces(c.Text))
End Select
End If
End If
dgvLoadTests.CancelEdit()
End If
End If
Catch ex As Exception
EH.strRetVal = gfrmID & "/dgvLoadTests_CellValidat
End Try
EH.ProcessMessages(Me, sbr, EH.strRetVal)
End Sub
'
'
'
Private Sub dgvLoadTests_KeyDown(sende
Try
EH.strRetVal = ""
nonNumbered = False
Select Case e.KeyCode
Case Keys.Enter Or Keys.Return
rowIDX = dgvLoadTests.CurrentCellAd
colIDX = dgvLoadTests.CurrentCellAd
If blnOEM Then
Select Case colIDX
Case 0 To 1 'Columns 0 & 1
Case dgvLoadTests.Columns.Count
If rowIDX < dgvLoadTests.Rows.Count - 1 Then 'This is any row other than the last row in the Grid
dgvLoadTests.CurrentCell = dgvLoadTests(2, rowIDX + 1)
Else
dgvLoadTests.Rows(rowIDX).
End If
Case Else
If rowIDX = dgvLoadTests.Rows.Count - 1 Then 'This is the last row
If Not colIDX = dgvLoadTests.Columns.Count
dgvLoadTests.CurrentCell = dgvLoadTests(colIDX + 1, rowIDX)
End If
dgvLoadTests.Rows(rowIDX).
Else
If colIDX >= 2 And colIDX < dgvLoadTests.Columns.Count
dgvLoadTests.CurrentCell = dgvLoadTests(colIDX + 1, rowIDX)
dgvLoadTests.Rows(rowIDX).
ElseIf colIDX = dgvLoadTests.Columns.Count
dgvLoadTests.CurrentCell = dgvLoadTests(2, rowIDX + 1)
dgvLoadTests.Rows(rowIDX).
Else
dgvLoadTests.CurrentCell = dgvLoadTests(colIDX + 1, rowIDX)
dgvLoadTests.Rows(rowIDX).
End If
End If
End Select
Else 'Take this branch for Non-OEM Tests (a single Sensor test)
Select Case rowIDX
Case 0
If colIDX = 1 Then
dgvLoadTests.Rows(rowIDX).
End If
Case dgvLoadTests.Rows.Count - 1 'TEST IS FINISHED at this point
'dgvLoadTests.Rows(rowIDX)
Case Else
dgvLoadTests.Rows(rowIDX).
End Select
End If
Case Keys.D0 To Keys.D9
Case Keys.NumPad0 To Keys.NumPad9
Case Keys.Delete
nonNumbered = False
dgvLoadTests.Rows(rowIDX).
Case Keys.Back
Case Else
nonNumbered = True
End Select
Catch ex As Exception
EH.strRetVal = gfrmID & "/dgvLoadTests_KeyDown() - " & ex.Message
End Try
EH.ProcessMessages(Me, sbr, EH.strRetVal)
End Sub
'
'
'
Private Sub dgvLoadTests_KeyPress(send
Try
rowIDX = dgvLoadTests.CurrentCell.R
colIDX = dgvLoadTests.CurrentCell.C
If e.KeyChar = Chr(13) Then
e.Handled = True
'SendKeys.Send("{TAB}")
If rowIDX = dgvLoadTests.Rows.Count - 1 Then
Else
End If
End If
EH.strRetVal = ""
Catch ex As Exception
EH.strRetVal = gfrmID & "/dgvLoadTests_KeyPress() - " & ex.Message
End Try
EH.ProcessMessages(Me, sbr, EH.strRetVal)
End Sub
'
'
'
Private Sub dgvLoadTests_MouseClick(se
Try
EH.strRetVal = ""
If Not blnManual Then
Dim col As Integer = dgvLoadTests.CurrentCell.C
If col = 5 Then
SetMatrix(Me.Name, cmbOutputUnit.Text, FaultyDeviceName)
End If
End If
Catch ex As Exception
EH.strRetVal = gfrmID & "/dgvLoadTests_MouseClick(
End Try
EH.ProcessMessages(Me, sbr, EH.strRetVal)
End Sub
I would try commenting out the code in the dgvLoadTests_KeyDown event handler that handles the Enter key:
Case Keys.Enter Or Keys.Return
rowIDX = dgvLoadTests.CurrentCellAddress.Y 'Get Row Index
colIDX = dgvLoadTests.CurrentCellAddress.X 'Get Column Index
...
ASKER
I tried commenting out the entire code in the KeyDown for the Keys.Enter or Keys.Return and that had no effect.
I also tried commenting out the 2 lines that you have in your previous post and that didn't work either.
I'm spending way to much time on this.
I also tried commenting out the 2 lines that you have in your previous post and that didn't work either.
I'm spending way to much time on this.
Well, remember that I am on the outside looking in, and the DataGridView is a strange beast.
If you comment out the SendKeys, and the code in the KeyDown for the {Enter} key, what happens?
If you comment out the SendKeys, and the code in the KeyDown for the {Enter} key, what happens?
ASKER
That's the current scenario and it's still acting weird. Advancing 1 row and 1 column to the right still.
I also see where you are changing CurrentCell in the dgvLoadTests_CellEndEdit event handler. Does this behavior happen when you are in edit mode, or not in edit mode?
ASKER
I don't understand the EditMode Events real well. When does the CellEndEdit Event fire? At what point am I not in EditMode? Below is the code that I have so far. It's current functionality is that when I enter a value in the cell in all the rows except for the last, the cursor advances to the next column, like it's suppose to. When I hit the enter key with nothing in the cell, it simply advances to the next row. When I'm in the last row and enter a value, the cursor advances to the next column, however, the value in the previous cell disappears. Below is the code that I have as of right now.
Private Sub dgvLoadTests_CellEndEdit(s ender As Object, e As DataGridViewCellEventArgs) Handles dgvLoadTests.CellEndEdit
Try
If colIDX = dgvLoadTests.Columns.Count - 1 Then
If rowIDX < dgvLoadTests.Rows.Count - 1 Then
dgvLoadTests.CurrentCell = dgvLoadTests(0, rowIDX + 1)
End If
Else
If rowIDX < dgvLoadTests.Rows.Count - 1 Then
SendKeys.Send("{up}")
End If
dgvLoadTests.CurrentCell = dgvLoadTests(colIDX + 1, rowIDX)
End If
Catch ex As Exception
EH.strRetVal = gfrmID & "/dgvLoadTests_CellEndEdit () - " & ex.Message
End Try
End Sub
'
'
'
Private Sub dgvLoadTests_CellValidatin g(sender As Object, e As DataGridViewCellValidating EventArgs) Handles dgvLoadTests.CellValidatin g
Try
EH.strRetVal = ""
rowIDX = dgvLoadTests.CurrentCellAd dress.Y 'Get Row Index
colIDX = dgvLoadTests.CurrentCellAd dress.X 'Get Column Index
If dgvLoadTests.Item(e.Column Index, e.RowIndex).IsInEditMode Then
If Not dgvLoadTests.Item(e.Column Index, e.RowIndex).ValueType Is GetType(Decimal) Then
Dim c As Control = dgvLoadTests.EditingContro l
Dim cell As DataGridViewCell = dgvLoadTests.CurrentCell
If Not Decimal.TryParse(c.Text, Nothing) Then
If c.Text = "" Then
Else
EH.strRetVal = "Invalid Numeric Value!" & "~I"
e.Cancel = True
End If
Else
Select Case e.RowIndex
Case 0
cell.Value = Format(c.Text, c.Text) 'Don't format the Load Values
Case Else
cell.Value = Format(c.Text, GetDecimalPlaces(c.Text))
End Select
End If
dgvLoadTests.CancelEdit()
End If
End If
Catch ex As Exception
EH.strRetVal = gfrmID & "/dgvLoadTests_CellValidat ing() - " & ex.Message
End Try
EH.ProcessMessages(Me, sbr, EH.strRetVal)
End Sub
'
'
'
Private Sub dgvLoadTests_KeyDown(sende r As Object, e As KeyEventArgs) Handles dgvLoadTests.KeyDown
Try
nonNumbered = False
Select Case e.KeyCode
Case Keys.Enter
rowIDX = dgvLoadTests.CurrentCellAd dress.Y 'Get Row Index
colIDX = dgvLoadTests.CurrentCellAd dress.X 'Get Column Index
Case Keys.D0 To Keys.D9
Case Keys.NumPad0 To Keys.NumPad9
Case Keys.Delete
nonNumbered = False
dgvLoadTests.Rows(rowIDX). Cells(colI DX).Value = ""
Case Keys.Back
Case Else
nonNumbered = True
End Select
Catch ex As Exception
EH.strRetVal = gfrmID & "/dgvLoadTests_KeyDown() - " & ex.Message
End Try
End Sub
'
'
'
Private Sub dgvLoadTests_KeyPress(send er As Object, e As KeyPressEventArgs) Handles dgvLoadTests.KeyPress
Try
If Not IsNumeric(e.KeyChar) Then
e.Handled = True
ElseIf e.KeyChar = Microsoft.VisualBasic.ChrW (Keys.Retu rn) Or e.KeyChar = Microsoft.VisualBasic.ChrW (Keys.Ente r) Then
If blnOEM Then
If colIDX = dgvLoadTests.Columns.Count - 2 Then
If rowIDX < dgvLoadTests.Rows.Count - 1 Then
dgvLoadTests.CurrentCell = dgvLoadTests(2, rowIDX + 1)
Else
'dgvLoadTests.Rows(rowIDX) .Cells(col IDX).Value = GetDecimalPlaces("00.0000" ) 'Get Multimeter Reading
End If
Else
If rowIDX = dgvLoadTests.Rows.Count - 1 Then
If colIDX = dgvLoadTests.Columns.Count - 3 Then
'dgvLoadTests.Rows(rowIDX) .Cells(col IDX).Value = GetDecimalPlaces("00.0000" ) 'Get Multimeter Reading. TEST IS FINISHED at this point
Else
'dgvLoadTests.Rows(rowIDX) .Cells(col IDX).Value = GetDecimalPlaces("00.0000" ) 'Get Multimeter Reading
dgvLoadTests.CurrentCell = dgvLoadTests(colIDX + 1, rowIDX)
End If
Else
If colIDX >= 1 And colIDX < dgvLoadTests.Columns.Count - 2 Then
'dgvLoadTests.Rows(rowIDX) .Cells(col IDX).Value = GetDecimalPlaces("00.0000" ) 'Get Multimeter Reading
End If
If colIDX = dgvLoadTests.Columns.Count - 3 Then
dgvLoadTests.CurrentCell = dgvLoadTests(2, rowIDX + 1)
Else
dgvLoadTests.CurrentCell = dgvLoadTests(colIDX + 1, rowIDX)
End If
End If
End If
Else 'Take this branch for Non-OEM Tests (a single Sensor test)
End If
End If
Catch ex As Exception
EH.strRetVal = gfrmID & "/dgvLoadTests_KeyPress() - " & ex.Message
End Try
EH.ProcessMessages(Me, sbr, EH.strRetVal)
End Sub
Private Sub dgvLoadTests_CellEndEdit(s
Try
If colIDX = dgvLoadTests.Columns.Count
If rowIDX < dgvLoadTests.Rows.Count - 1 Then
dgvLoadTests.CurrentCell = dgvLoadTests(0, rowIDX + 1)
End If
Else
If rowIDX < dgvLoadTests.Rows.Count - 1 Then
SendKeys.Send("{up}")
End If
dgvLoadTests.CurrentCell = dgvLoadTests(colIDX + 1, rowIDX)
End If
Catch ex As Exception
EH.strRetVal = gfrmID & "/dgvLoadTests_CellEndEdit
End Try
End Sub
'
'
'
Private Sub dgvLoadTests_CellValidatin
Try
EH.strRetVal = ""
rowIDX = dgvLoadTests.CurrentCellAd
colIDX = dgvLoadTests.CurrentCellAd
If dgvLoadTests.Item(e.Column
If Not dgvLoadTests.Item(e.Column
Dim c As Control = dgvLoadTests.EditingContro
Dim cell As DataGridViewCell = dgvLoadTests.CurrentCell
If Not Decimal.TryParse(c.Text, Nothing) Then
If c.Text = "" Then
Else
EH.strRetVal = "Invalid Numeric Value!" & "~I"
e.Cancel = True
End If
Else
Select Case e.RowIndex
Case 0
cell.Value = Format(c.Text, c.Text) 'Don't format the Load Values
Case Else
cell.Value = Format(c.Text, GetDecimalPlaces(c.Text))
End Select
End If
dgvLoadTests.CancelEdit()
End If
End If
Catch ex As Exception
EH.strRetVal = gfrmID & "/dgvLoadTests_CellValidat
End Try
EH.ProcessMessages(Me, sbr, EH.strRetVal)
End Sub
'
'
'
Private Sub dgvLoadTests_KeyDown(sende
Try
nonNumbered = False
Select Case e.KeyCode
Case Keys.Enter
rowIDX = dgvLoadTests.CurrentCellAd
colIDX = dgvLoadTests.CurrentCellAd
Case Keys.D0 To Keys.D9
Case Keys.NumPad0 To Keys.NumPad9
Case Keys.Delete
nonNumbered = False
dgvLoadTests.Rows(rowIDX).
Case Keys.Back
Case Else
nonNumbered = True
End Select
Catch ex As Exception
EH.strRetVal = gfrmID & "/dgvLoadTests_KeyDown() - " & ex.Message
End Try
End Sub
'
'
'
Private Sub dgvLoadTests_KeyPress(send
Try
If Not IsNumeric(e.KeyChar) Then
e.Handled = True
ElseIf e.KeyChar = Microsoft.VisualBasic.ChrW
If blnOEM Then
If colIDX = dgvLoadTests.Columns.Count
If rowIDX < dgvLoadTests.Rows.Count - 1 Then
dgvLoadTests.CurrentCell = dgvLoadTests(2, rowIDX + 1)
Else
'dgvLoadTests.Rows(rowIDX)
End If
Else
If rowIDX = dgvLoadTests.Rows.Count - 1 Then
If colIDX = dgvLoadTests.Columns.Count
'dgvLoadTests.Rows(rowIDX)
Else
'dgvLoadTests.Rows(rowIDX)
dgvLoadTests.CurrentCell = dgvLoadTests(colIDX + 1, rowIDX)
End If
Else
If colIDX >= 1 And colIDX < dgvLoadTests.Columns.Count
'dgvLoadTests.Rows(rowIDX)
End If
If colIDX = dgvLoadTests.Columns.Count
dgvLoadTests.CurrentCell = dgvLoadTests(2, rowIDX + 1)
Else
dgvLoadTests.CurrentCell = dgvLoadTests(colIDX + 1, rowIDX)
End If
End If
End If
Else 'Take this branch for Non-OEM Tests (a single Sensor test)
End If
End If
Catch ex As Exception
EH.strRetVal = gfrmID & "/dgvLoadTests_KeyPress() - " & ex.Message
End Try
EH.ProcessMessages(Me, sbr, EH.strRetVal)
End Sub
Here is link to the DataGridView events, with a short description for each:
DataGridView Events
http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview_events(v=vs.110).aspx
CellBeginEdit -- Occurs when edit mode starts for the selected cell.
The point at which the edit mode starts, depends on the EditMode property.
DataGridView.EditMode Property
http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.editmode(v=vs.110).aspx
EditOnEnter
Editing begins when the cell receives focus. This mode is useful when pressing the TAB key to enter values across a row, or when pressing the ENTER key to enter values down a column.
EditOnF2
Editing begins when F2 is pressed while the cell has focus. This mode places the selection point at the end of the cell contents.
EditOnKeystroke
Editing begins when any alphanumeric key is pressed while the cell has focus.
EditOnKeystrokeOrF2
Editing begins when any alphanumeric key or F2 is pressed while the cell has focus.
EditProgrammatically
Editing begins only when the BeginEdit method is called.
DataGridView Events
http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview_events(v=vs.110).aspx
CellBeginEdit -- Occurs when edit mode starts for the selected cell.
The point at which the edit mode starts, depends on the EditMode property.
DataGridView.EditMode Property
http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.editmode(v=vs.110).aspx
EditOnEnter
Editing begins when the cell receives focus. This mode is useful when pressing the TAB key to enter values across a row, or when pressing the ENTER key to enter values down a column.
EditOnF2
Editing begins when F2 is pressed while the cell has focus. This mode places the selection point at the end of the cell contents.
EditOnKeystroke
Editing begins when any alphanumeric key is pressed while the cell has focus.
EditOnKeystrokeOrF2
Editing begins when any alphanumeric key or F2 is pressed while the cell has focus.
EditProgrammatically
Editing begins only when the BeginEdit method is called.
ASKER
There is just so many different events to choose from which takes me back to my original question. It seems you can do the same thing in multiple events.
The scenario for this functionality is that the cursor will be placed in a cell awaiting for the User to press/click the Enter Key. At this point, a reading from a PLC (there is code that automatically retrieves a decimal value) will be taken and the value inserted into the Cell. The User also has the option to manually change this retrieved value by entering their own numeric value.
With the above requirement, how would YOU code this? Keep in mind that the cursor has to advance horizontally and not vertically.
The scenario for this functionality is that the cursor will be placed in a cell awaiting for the User to press/click the Enter Key. At this point, a reading from a PLC (there is code that automatically retrieves a decimal value) will be taken and the value inserted into the Cell. The User also has the option to manually change this retrieved value by entering their own numeric value.
With the above requirement, how would YOU code this? Keep in mind that the cursor has to advance horizontally and not vertically.
Another issue is that there is a confusing array of events that can conflict, especially if you require a lot of different functionality. Key events during EditMode can really complicate the situation.
If you are asking me how I would approach this problem, then we need to revisit a previous comment, with more detail.
Here is some code to show how it all works.
If you are asking me how I would approach this problem, then we need to revisit a previous comment, with more detail.
Here is some code to show how it all works.
Form1.vb:
Public Class Form1
Private ReadOnly _dataSource As Object(,) = New Object(9, 4) {}
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
DataGridView1.VirtualMode = True
DataGridView1.RowCount = 5
DataGridView1.ColumnCount = 5
End Sub
Private Sub DataGridView1_CellValueNeeded(sender As Object, e As DataGridViewCellValueEventArgs) Handles DataGridView1.CellValueNeeded
e.Value = _dataSource(e.RowIndex, e.ColumnIndex)
End Sub
Private Sub DataGridView1_CellValuePushed(sender As Object, e As DataGridViewCellValueEventArgs) Handles DataGridView1.CellValuePushed
_dataSource(e.RowIndex, e.ColumnIndex) = e.Value
End Sub
End Class
CustomDataGridView.vb:
Imports System.ComponentModel
Imports System.Windows.Forms
Public Enum EnterBehavior
NextRow
NextColumn
End Enum
''' <summary>
''' A DataGridView with a StandardEnter property which behaves
''' like StandardTab.
''' </summary>
Public Class CustomDataGridView
Inherits DataGridView
''' <summary>
''' Sets the behavior for the {Enter} key. Either next row (default),
''' or next column.
''' </summary>
<Category("Behavior"), Description("Disable default edit/advance to next row behavior of of the Enter key.")> _
Public Property EnterKeyBehavior() As EnterBehavior
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, ByVal keyData As Keys) As Boolean
If keyData = Keys.Enter Then
SendKeys.Send("{TAB}")
Return True
End If
Return False
End Function
End Class
When you build an application with a custom control included, the custom control should be added to the ToolBox, so that you can drag and drop the control onto the Form designer surface.
The ProcessCmdKey works for either the edit mode, or the regular mode.
The ProcessCmdKey works for either the edit mode, or the regular mode.
Here is a good resource to explain the DataGridView:
DataGridView FAQ Google Document
https://docs.google.com/file/d/0B5SkDFb3doulcFp6VU5RMDVCUkE/edit
DataGridView FAQ Google Document
https://docs.google.com/file/d/0B5SkDFb3doulcFp6VU5RMDVCUkE/edit
ASKER
Thanks, I'll study this for awhile and see what I can make of it.
ASKER
I'm just not getting it!
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Your link is requiring me to logon. I tried using my regular login ID and it wouldn't work.
Nevermind...my bad! I'm in...
Nevermind...my bad! I'm in...
ASKER
Ok,
Is VirtualMode used for Databound dgv's only? I tried setting my grid's virtualmode to true and I lost all my header info. Certain cells of my Grid is pre-populated based on User Input. A button is pressed and all the logic is in the Button's click event. Can that be moved to the CellValueNeeded Event? If so, how can it be triggered based on User Input? Where can I check to make sure only numeric data is input?
Thanks!
Is VirtualMode used for Databound dgv's only? I tried setting my grid's virtualmode to true and I lost all my header info. Certain cells of my Grid is pre-populated based on User Input. A button is pressed and all the logic is in the Button's click event. Can that be moved to the CellValueNeeded Event? If so, how can it be triggered based on User Input? Where can I check to make sure only numeric data is input?
Thanks!
When you work with virtual mode, your program is required to supply all information, and store the data entered. It was an easy way to show you an example of how the DataGridView works when entering values in the cells, and pressing the {Enter} key.
ASKER
LearnedOne,
Regarding post ID: 39721660, I was wondering about the Function "ProcessCmdKey"?
Is there anyway of being able to toggle the SendKey command to "{ENTER}" under one condition and "{TAB}" under another condition? I only say this because I tried to use a global boolean variable and it just hung my app.
The scenario was that my grid can be presented in 2 different ways, one showing columnar data and the other showing row data. When it's in Row Data mode, hitting the enter key should move the cursor down a row (which is it's default anyway) rather than horizontally.
Regarding post ID: 39721660, I was wondering about the Function "ProcessCmdKey"?
Is there anyway of being able to toggle the SendKey command to "{ENTER}" under one condition and "{TAB}" under another condition? I only say this because I tried to use a global boolean variable and it just hung my app.
The scenario was that my grid can be presented in 2 different ways, one showing columnar data and the other showing row data. When it's in Row Data mode, hitting the enter key should move the cursor down a row (which is it's default anyway) rather than horizontally.
I had an enumeration to control the behavior (EnterKeyBehavior), but it didn't make it into the logic.
Here is the change, adding a check for the EnterKeyBehavior property. You can change that on the Form designer where the control is hosted.
Here is the change, adding a check for the EnterKeyBehavior property. You can change that on the Form designer where the control is hosted.
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, ByVal keyData As Keys) As Boolean
If EnterKeyBehavior = EnterKey.NextColumn AndAlso keyData = Keys.Enter Then
SendKeys.Send("{TAB}")
Return True
End If
Return False
End Function
ASKER
I put the above code in your CustomDataGridView class and it said "EnterKey" was undeclared. I'm correct in making this change in YOUR code right? Please correct me if I'm wrong.
Thanks!
Thanks!
At the top of the class module was the enumeration declaration, that you didn't notice:
Public Enum EnterBehavior
NextRow
NextColumn
End Enum
ASKER
No, actually I did see that. But I tried to alter your original code (ID: 39721660) using the new code in post ID: 39726818. When I tried this, the "EnterKey" object was undeclared.
Can you show me the code please?
ASKER
Here is the code that I inserted into my KeyUp Event.
Your code is below. I'm getting and undeclared warning on the "EnterKey" object within the ProcessCmdKey Function.
If gblnOEM Then
cDGV.EnterKeyBehavior = EnterBehavior.NextColumn
Else
cDGV.EnterKeyBehavior = EnterBehavior.NextRow
End If
Your code is below. I'm getting and undeclared warning on the "EnterKey" object within the ProcessCmdKey Function.
Imports System.ComponentModel
Imports System.Windows.Forms
Public Enum EnterBehavior
NextRow
NextColumn
End Enum
''' <summary>
''' A DataGridView with a StandardEnter property which behaves
''' like StandardTab.
''' </summary>
Public Class CustomDataGridView
Inherits DataGridView
''' <summary>
''' Sets the behavior for the {Enter} key. Either next row (default),
''' or next column.
''' </summary>
<Category("Behavior"), Description("Disable default edit/advance to next row behavior of of the Enter key.")> _
Public Property EnterKeyBehavior() As EnterBehavior
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, ByVal keyData As Keys) As Boolean
If EnterKeyBehavior = EnterKey.NextColumn AndAlso keyData = Keys.Enter Then
SendKeys.Send("{TAB}")
Return True
End If
Return False
End Function
End Class
Sorry for my dyslexia:
EnterBehavior.NextColumn
EnterBehavior.NextColumn
ASKER
No worries...that worked too!
Thanks again for your help!
Thanks again for your help!