KeyDown Event to next row - vb.net

I created this form in VS
The NumPlace TextBox is intalized to 1 automatically, I want when I press on the Enter key to increment the NumPlace automatically in the next row.
This is the code I wrote :
Private Sub DataGridView1_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles DataGridView1.KeyDown
If e.KeyCode = Keys.Enter Then
MsgBox("Enter key is pressed !")
End If
End Sub
But It doesn't work it only works when I'm selecting some row end press on "Enter" but when I change the value of the ComboBox or when I select the NumPlace TextBox and then I press on Enter the event doesn't work.

You need to check ColIndex and RowIndex......................
Dim currCell As DataGridViewCell = DataGridView1.CurrentCell

The DataGridView1_KeyDown event will only fire when the focus is on DataGridView1. try handling Form1_KeyDown Event instead.
Private Sub Form1_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.Enter Then
MsgBox("Enter key is pressed !")
End If
End Sub
However, you should set Form1 KeyPreview property to True in the Form Designer or in Form Load so that the form receives key events before the event is passed to the control that has focus.
see this for more info

The solution is to use the event KeyUp instead of KeyDown

Related

Detect when a user stops editing a DataGridViewCell

I am working on a VB.Net project and am trying to set up a DataGridView so that users can edit data. I'd like to set it up so that when a user finishes editing a cell, either through navigating to a new cell, or by pressing the Enter key, something happens.
I started by creating a method to store the old data that was in the cell:
Private oldCellVal As String = ""
Private oldCellRow As Integer
Private oldCellCol As Integer
Private Sub dg_CellBeginEdit(ByVal sender As Object, ByVal e As DataGridViewCellCancelEventArgs) Handles dg.CellEndEdit
oldCellVal = dg.Rows(e.RowIndex).Cells(e.ColumnIndex).Value
oldCellRow = e.RowIndex
oldCellCol = e.ColumnIndex
End Sub
Now my next logical step was to create a KeyDown event for the DataGridView
Private Sub dg_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs) Handles dg.KeyDown
If e.KeyCode <> Keys.Enter Then
If dg.IsCurrentCellInEditMode() Then
If MessageBox.Show("Would you like to cancel editing?", "Confirmation", MessageBoxButtons.YesNoCancel) = DialogResult.Yes Then dg.CurrentCell.Value = oldCellVal
End If
ElseIf e.KeyCode = Keys.Enter Then
If MessageBox.Show("Would you like to save these changes?", "Confirmation", MessageBoxButtons.YesNoCancel) = DialogResult.Yes Then MessageBox.Show("Saved")
End If
End Sub
Well here we have our first problem. While the DataGridView is in edit mode for a cell, it does not register KeyDown events. No matter what I did, I could not trigger the KeyDown event handler until after moving to another cell. Essentially I need to hit Enter twice in order for the MessageBox to appear.
So from here I figured, okay, lets put together an event handler for EditingControlsShowing that should work!
Private Sub dg_EditingControlsSHow(ByVal sender As Object, ByVal e As DataGridViewEditingControlShowingEventArgs) Handles dg.EditingControlShowing
MessageBox.Show("Please work")
End Sub
And here the MessageBox only appears once the editting has begun, and I can do nothing once I am finished.
So I am utterly confused as to what to do here. To restate what I want to do I am trying to set up a DataGridView that has the following functionality for the Cells:
While editing the value within a Cell, if you press the Enter key, you get a prompt asking if you want to save your changes.
If instead of Enter, you press any other key that would turn off Cell editing (like Tab or the Arrow Keys) you get a prompt asking if you are sure you wish to cancel editing.
I really don't know what to do here, so any and all help is greatly appreciated.
First you need to check if you are in edit mode:
Private isEditing As Boolean = False
Private Sub DataGridView1_CellBeginEdit(sender As Object, e As DataGridViewCellCancelEventArgs) Handles DataGridView1.CellBeginEdit
isEditing = True
End Sub
Private Sub DataGridView1_CellEndEdit(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellEndEdit
isEditing = False
End Sub
Then you can override the ProcessCmdKey function:
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, keyData As Keys) As Boolean
If isEditing = True Then
Select Case keyData
Case Keys.Left
Case Keys.Right
Case Keys.Enter
Case Else
End Select
End If
Return MyBase.ProcessCmdKey(msg, keyData)
End Function
Return True from the function if you want to suppress the key.

Visual Basic e.SuppressKeyPress Does Not Work When Clicking a Button with Button.PerformClick()

I am trying to make my program press a button in the form if the "enter" key is pressed while in a specific text box.
I have used similar code to change focus between text boxes, and it works perfectly fine.
Private Sub TextBox1_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox1.KeyDown
If e.KeyCode = Keys.Enter Then
e.SuppressKeyPress = True
TextBox2.Focus()
End If
End Sub
In this instance, the Windows noise does not play, and the focus is changed from TextBox1 to TextBox2.
However, I tried to implement the same code while only changing one line.
Private Sub TextBox2_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox2.KeyDown
If e.KeyCode = Keys.Enter Then
e.SuppressKeyPress = True
Button2.PerformClick()
End If
End Sub
The "e.SuppressKeyPress = True" does not stop the Windows noise from playing.
I have researched this for about three hours now, and have come up empty handed multiple times. I have tried setting the button to the default "AcceptButton", but then when I press enter in ANY text box, then the button is pressed. I only want the button to be pressed if enter is pressed in TextBox2.
I should also mention, simply pressing the button does not make the noise. Only if the user presses "enter" in TextBox2.
EDIT 1 - I have tried to debug as best I can, and it appears to only be happening when the user presses enter.
Private Sub TextBox2_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox2.KeyDown
If e.KeyCode = Keys.Enter Then
e.SuppressKeyPress = True
End If
End Sub
Removing the button click from the code (see above) makes the Windows noise stop. I'm completely at a loss here...
I fixed the issue by changingPrivate Sub TextBox2_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox2.KeyDown to Private Sub TextBox1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox1.KeyPressand only using e.Handled = true.
It seems the Performclick command sends your code off the scope of the keydown command, it is processed as a key event nested into a key event, as a SendKeys.SendWait{F6} command in this same context would, for example.
In other words, it's like you need to call SuppressKeyPress another time. I don't know how to do that.

On lable focus enter press to raise event

I'm trying to get this sub to execute when my lable has focus and someone clicks "Enter" This is the code I have so far...
Private Sub AssignOwnersLabel_Click() Handles AssignOwnersLabel.Click
Dim repository As OwnerRepositorySvc.OwnerRepositoryClient = Nothing
For Each programRow As DataGridViewRow In ProgramOwnerFill.SelectedRows
programRow.Cells(0).Value = AssignOwnersTXTBox.Text
Next
repository = OpenRepository()
repository.SaveOwners(_ds)
_ds.AcceptChanges()
CloseRepository(repository)
Dim dataview As DataView = _ds.ProgramOwners.DefaultView
dataview.Sort = _ds.ProgramOwners.EmployeeIDColumn.ColumnName
Me.ProgramOwnersBindingSource.DataSource = dataview
End Sub
I think to get this to work I need to do something with "keychar" but I'm not sure how that would look. Thanks for help!
To find out if the user pressed the enter key, do this:
Private Sub Form1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Me.KeyPress
If e.KeyCode = Keys.Enter Then
' Put logic here for when the user pressed enter
End if
End Sub
Note: There are several key-type events, such as KeyPress, KeyDown and KeyUp.

Form keydown event and textbox keydown event

Private Sub AccountType_KeyDOWN(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown
If e.KeyCode = Keys.Return Then
ProcessTabKey(True)
End If
End Sub
Private Sub anytextbox_Enter(sender As Object, e As EventArgs) Handles Twitter.Enter, Email.Enter, PhoneNoOffice.Enter, PhoneNoHome.Enter, PhoneNoMobile.Enter, EName.Enter, AName.Enter, IDCode.Enter, ExpiryDate.Enter, BankAccount.Enter
Dim txt As TextBox = DirectCast(sender, TextBox)
stroldvalue = txt.Text
End Sub
Private Sub anytextbox_KeyDown(sender As Object, e As KeyEventArgs) Handles Twitter.KeyDown, Email.KeyDown, PhoneNoOffice.KeyDown, PhoneNoHome.KeyDown, PhoneNoMobile.KeyDown, EName.KeyDown, AName.KeyDown, IDCode.KeyDown, ExpiryDate.KeyDown, BankAccount.KeyDown
Dim txt As TextBox = DirectCast(sender, TextBox)
If e.KeyCode = Keys.Enter Or e.KeyCode = Keys.Tab Then
If txt.Text <> stroldvalue Then
connectunauth()
cmd = New SqlCommand("Insert into changes values(#id,#txtname,#oldval,#newval)", Variables.UnauthCon)
cmd.Parameters.AddWithValue("#id", CustomerNo.Text)
cmd.Parameters.AddWithValue("#txtname", txt.Name)
cmd.Parameters.AddWithValue("#oldval", stroldvalue)
cmd.Parameters.AddWithValue("#newval", txt.Text)
cmd.ExecuteNonQuery()
UnauthCon.Dispose()
NOCHANGE = True
End If
End If
End Sub
In the above code i face the following error:
On entry into one textbox, the value is saved in stroldvalue.
On pressing enter after changing in the above, the form_keydown event triggers first, which runs the anytextbox_enter event causing the stroldvalue to be overwritten by the next textbox value. and then the textbox keydown event triggers.
I tried keypress event for the form, but keypress event does not capture enter key press on combobox.
What should i do so that the keydown of form triggers after textbox keydown event.

ComboBox's SelectedIndexChanged event not being called on Enter

I'm working on VS 2010 with VB using .NET Framework 4.0
I have a combobox. It has some items in it and displays just fine. Here's where it gets a little weird:
If I click the drop-down arrow on the combobox and CLICK on the item I want, SelectedIndexChanged is called - good.
If I click inside the text area of the combobox and start typing what I want selected and finish it by pressing the up (or down) key, SelectedIndexChanged is called - also good.
If I click the drop-down arrow on the combobox and start typing what I want selected and finish it by pressing ENTER, SelectedIndexChanged is not called - PROBLEM.
Is there a different event that is caused by the ENTER in the last case? I've tried using the TextChanged and TextUpdate events, but those do not seem to be working:
Private Sub cmbStatus_TextChanged(sender As System.Object, e As System.EventArgs) Handles cmbStatus.TextChanged
If e.Equals(Keys.Enter) Then
Call SomeMethod()
End If
Should I use something besides e.Equals(Keys.Enter)?
Is there another event I should be looking for?
EDIT:
An example of the items in the ComboBox are:
10 - NEW ENTRY AND COMPLETENESS CHECK ---> this is the most common type
13 - ASSIGNED TO TRB/HRB ---> there are a few with '/'
60 - EXTERNAL (HOLD UNTIL FURTHER NOTICE) ---> there are a few with '(' and ')'
Basically, the type of each listing is "## - SOME TEXT".
Disclaimer: this is written in C# - let me know if you need it translated to VB.
private void comboBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
//It's important to also check that the Combo Box is displaying its Drop Down. If
//you want this to execute even when it is not displayed, remove the check for
//comboBox1.DroppedDown.
if (e.KeyCode == Keys.Enter && comboBox1.DroppedDown &&
!string.IsNullOrEmpty(comboBox1.Text))
{
int index;
//Attempt to locate the string typed in by the user. An index of -1
//means it was not found.
if ((index = comboBox1.FindStringExact(comboBox1.Text)) != -1)
{
//Update the SelectedIndex.
comboBox1.SelectedIndex = index;
}
}
}
Interestingly, the docs say that we should be using the SelectionChangeCommitted event instead of the SelectedIndexChanged event when handling selection changes made by the user. It is necessary to do so in this case as the SelectedIndexChanged event fires twice using my approach.
Edit:
To prevent the user from having to type the entire string, use the advice from Adi's answer: go to the properties of the combo box and set set AutoCompleteMode to SuggestAppend and AutoCompleteSource to ListItems - I actully used these settings when creating my answer, so it should work for you.
Option Strict On
Public Class Form1
Friend WithEvents ComboBox1 As New ComboBox With {.Parent = Me}
Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
ComboBox1.Items.AddRange({"hello", "tes1ted", "word", "item", "tes2ted"})
ComboBox1.Text = ComboBox1.Items(0).ToString
End Sub
Private Sub ComboBox1_KeyUp(ByVal sender As Object, ByVal e As KeyEventArgs) Handles ComboBox1.KeyUp
'You can put this in the keydown event, or adapt it a small bit and put it in the keypress event
'putting it in the textchanged event is problematic and not recommended.
Dim OriginalText As String = ComboBox1.Text
If e.KeyCode = Keys.Enter Then
If ComboBox1.SelectionLength > 0 Then
ComboBox1.Text = ComboBox1.Text
ComboBox1.SelectionLength = 0
ComboBox1.SelectionStart = ComboBox1.Text.Length
End If
End If
If Not IsTextKey(e.KeyCode) Then Exit Sub
Dim Filter As String = ComboBox1.Text & "*"
If Filter.Length = 1 Then Exit Sub
For I = 0 To ComboBox1.Items.Count - 1
If LCase(ComboBox1.Items(I).ToString) Like LCase(Filter) Then
ComboBox1.SelectedItem = ComboBox1.Items(I)
ComboBox1.Select(OriginalText.Length, (ComboBox1.Text.Length - OriginalText.Length))
Exit Sub
End If
Next
End Sub
Function IsTextKey(ByVal Key As Integer) As Boolean
Select Case True
Case Key = Keys.Up : Return False
Case Key = Keys.Down : Return False
Case Key = Keys.Left : Return False
Case Key = Keys.Right : Return False
Case Key = Keys.Back : Return False
Case Key = Keys.Delete : Return False
Case Key = Keys.LWin : Return False
Case Key = Keys.RWin : Return False
'add whatever I missed
'return false if the key either removes text from the textbox
'or does not produce a character
Case Else
'return true if the key produces a visible character(including space)
Return True
End Select
End Function
End Class
Private Sub ComboBox1_KeyUp(sender As System.Object, e As System.Windows.Forms.KeyEventArgs) Handles ComboBox1.KeyUp
If e.KeyCode = Keys.Enter Then
MessageBox.Show(ComboBox1.SelectedText)
Call SomeMethod()
End If
End Sub
I believe that you should set AutoCompleteMode to SuggestAppend and AutoCompleteSource to ListItems. This way, if what you type in is sustainable with the items loaded in the ComboBox, by writing it down and finding that item, when pressed Enter, the SelectedIndexChanged will be fired (even if a match wouldn't be found - the first in the list will be selected)
I've prepared something to point out this to you.
Regards,
Adi Konstantin
Subscribe to the KeyPressed event:
Private Sub yourComboBox_KeyPressed(sender As System.Object, e As System.KeyPressedEventArgs) Handles yourComboBox.KeyPressed
If e.KeyChar.Equals((char)Keys.Enter) Then
Call SomeMethod()
End If
this will helps your problems
Private Sub ComboBox1_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles ComboBox1.KeyDown
If e.KeyCode = Keys.Enter Then
MsgBox("hello")'call some functions
End If
End Sub
Can you let me know if this works for you?
Private Sub ComboBox1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles ComboBox1.KeyPress
If e.KeyChar = Chr(13) Then
ComboBox1_SelectedIndexChanged(sender, e)
End If
End Sub
Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
MsgBox(ComboBox1.Text)
'Your code here
End Sub
I had a similar problem when the combobox dropdownstyle was set to simple with autocomplete set to append, sourcing from my listitems. My workaround was to have a string variable save the combobox text upon each textchanged event. That way, when ENTER is pressed, you can retrieve the deleted text and reassign it to the combobox text.
'Global declaration
'Global declaraion
dim selected_text as string = ""
Private Sub combobox_textchanged(sender As Object, e As EventArgs) Handles combobox.TextChanged
If combobox.Text IsNot Nothing And combobox.Text <> "" Then
selected_text = combobox.Text
End If
End Sub
Private Sub combobox_keydown(sender As Object, e As KeyEventArgs) Handles combobox.KeyDown
If e.KeyCode = Keys.Enter Then
combobox.Text = selected_text
'put logic here
End If
End Sub
There are some great answers above, but I liked that I didn't need to sort out all the command keys and arrows etc.
Close the list manualy on PreviewKeyDown event:
Private Sub cmbStatus_PreviewKeyDown(sender As ComboBox, e As PreviewKeyDownEventArgs) Handles cmbStatus.PreviewKeyDown
If e.KeyCode = Keys.Enter Then sender.DroppedDown = False
End Sub