VB.NET Textbox KeyDown Event Not Firing - vb.net

So,
I have a textbox on a tabcontrol page, and when someone tabs out of the textbox, it is suppose to move to the next tab. This was working great before I switched the form from a UserControl to an actual Form. This change did not change actual code.
So now, I have tried everything. I have the textbox to set to AcceptTab = True, and I have KeyPreview = False (because if the form grabs the event before the textbox does, it would mess things up I am assuming).
Here is my code for the textbox:
Private Sub txtMsgDTG_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs) Handles txtMsgDTG.KeyDown
'check for tabbed out
If e.KeyCode = Keys.Tab Then
'If the user tabs into this field after filling out the necessary fields ...
If txtMsgDTG.Text = String.Empty Then
'If the user left the field BLANK ...
'Move to next page:
TabControl1.TabPages(0).Enabled = True
TabControl1.TabPages(1).Enabled = True
TabControl1.TabPages(2).Enabled = False
TabControl1.TabPages(3).Enabled = False
TabControl1.TabPages(4).Enabled = False
TabControl1.SelectedIndex = 1
Else
'If the user did NOT leave the field blank ...
'validate message DTG
Dim dtgCheck As String
dtgCheck = ValidateDTG(txtMsgDTG.Text)
If dtgCheck <> "valid" Then
MsgBox(dtgCheck)
Else
'Move to next page:
TabControl1.TabPages(0).Enabled = True
TabControl1.TabPages(1).Enabled = True
TabControl1.TabPages(2).Enabled = False
TabControl1.TabPages(3).Enabled = False
TabControl1.TabPages(4).Enabled = False
TabControl1.SelectedIndex = 1
End If
End If
End If
End Sub
Any ideas guys?

The quick fix:
txtMsgDTG.Multiline = True
The other fix where you can keep Multiline = False is to subscribe to the TextBox's PreviewKeyDown event:
Private Sub txtMsgDTG_PreviewKeyDown(ByVal sender As Object, ByVal e As PreviewKeyDownEventArgs) Handles txtMsgDTG.PreviewKeyDown
If e.KeyCode = Keys.Tab Then
e.IsInputKey = True
End If
End Sub

Related

How can I use the same code without having to retype it every time in different subs?

So I have a textbox that I only want to allow numbers in, I have the code to do it and it works fine. However I want to use it in a few textboxes, how can I use the same code without having to retype it in each textbox's KeyDown and KeyPress Subs?
The code I'm using in the KeyDown Subs is
If e.KeyCode = Keys.Back Then
BACKSPACE = True
Else
BACKSPACE = False
End If
and in the KeyPress subs I'm using
If BACKSPACE = False Then
Dim allowedChars As String = "0123456789"
If allowedChars.IndexOf(e.KeyChar) = -1 Then
e.Handled = True
End If
End If
I'm using this code for a few textboxes and was wondering how I can clean this up a bit. Can I? Thank you for your help and time!
you could simply set the handler for the event to handle the other objects and they will share that code
Private Sub txtDim0_Validated(sender As Object, e As EventArgs) Handles txtDim0.Validated, txtDim1.Validated, txtDim2.Validated, txtDim3.Validated, txtDim4.Validated, txtDim5.Validated, txtDim7.Validated, txtDim7.Validated
Dim iNewIndex As Integer
If ErrorProvider1.Tag <> "" Then
For icount = 0 To Len(ErrorProvider1.Tag) - 1
iNewIndex = Val(ErrorProvider1.Tag.ToString.Substring(icount, 1))
ErrorProvider1.SetError(txtDims(iNewIndex), String.Empty)
Next
ErrorProvider1.Tag = ""
Else
' get the index based on the name
Dim index As Integer = Val(sender.name.ToString.Substring(Len("txtDim")))
ErrorProvider1.SetError(txtDims(index), String.Empty)
End If
End Sub
You could make your own version of the TextBox control that inherits from the base TextBox and extends it with your custom code.
For example:
Public Class CleverTextBox
Inherits TextBox
Private BACKSPACE As Boolean = False
Private Sub CleverTextBox_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.Back Then
BACKSPACE = True
Else
BACKSPACE = False
End If
End Sub
Private Sub CleverTextBox_KeyPress(sender As Object, e As KeyPressEventArgs) Handles Me.KeyPress
If BACKSPACE = False Then
Dim allowedChars As String = "0123456789"
If allowedChars.IndexOf(e.KeyChar) = -1 Then
e.Handled = True
End If
End If
End Sub
End Class
Then recompile your project, and you should see that the new CleverTextBox control has been added to the Toolbox panel, and you can drag and drop it on to your form.

Set the Progress Bar Value according to data entered?

How can Set the Progress Bar Value increasing/ decreasing according to data entered in each controls on a form ? I mean, I am working with number of controls, so go for a sample [Suppose I have four textboxes, Progress Bar Maximum 100, when entering txt_1 Progress value have to increase to 100/4= 25, if I remove data from txt_1 the Value should decreased to Zero.
Sorry for my language, I am not good in English.
Can any one help me, please..... Thank You.
The Firs thing you do is set the progressbar maximum in your formload event to the number of textboxes you are using.
Dim TextBoxNumber As Integer = 4
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ProgressBar1.Maximum = TextBoxNumber
End Sub
Then you need to make 2 events.
1. TextBox enter event."Private Sub TextBox_Enter(sender As Object, e As EventArgs)"
2. TextBox TextChanged event"Private Sub TextBox_TextChanged(sender As Object, e As EventArgs)"
Then Link all the textboxes you want to use to the events.
In these events you will use the Sender.
Make a Dim and convert the sender to type Textbox to use its properties." Dim TextControl As TextBox = CType(sender, TextBox)"
In the Enter event you count the text that is entered in the textbox.
If the count is 0 you set the boolean to true and if its more than 0 you set the Boolean to False.
This Boolean you will use in the Text Change event.
Dim CheckTextBox As Boolean
Private Sub TextBox_Enter(sender As Object, e As EventArgs) Handles TextBox4.Enter, TextBox3.Enter, TextBox2.Enter, TextBox1.Enter
Dim TextControl As TextBox = CType(sender, TextBox)
If TextControl.Text.Count > 0 Then
CheckTextBox = False
Else
CheckTextBox = True
End If
End Sub
In the Text Change event you need to do a few things.
1.Use a if statement to check if the textbox is empty."This will only trigger if the user deletes the text in the textbox."
So if empty remove 1 from the progressbar and set CheckTextBox"Boolean" to True
"ProgressValue = ProgressValue - 1"
"CheckTextBox = True"
2.Then use a ElseIf to check if the CheckTextBox"Boolean" is True.
If true add 1 to progressbar and set Boolean to false.
"ProgressValue = ProgressValue + 1"
"CheckTextBox = False"
You need to set the Boolean to false because otherwise you will add 25 for every time you add somthing to the textbox.
Dim ProgressValue As Integer
Private Sub TextBox_TextChanged(sender As Object, e As EventArgs) Handles TextBox4.TextChanged, TextBox3.TextChanged, TextBox2.TextChanged, TextBox1.TextChanged
Dim TextControl As TextBox = CType(sender, TextBox)
If TextControl.Text = "" Then
ProgressValue = ProgressValue - 1
CheckTextBox = True
ElseIf CheckTextBox = True Then
ProgressValue = ProgressValue + 1
CheckTextBox = False
End If
ProgressBar1.Value = ProgressValue
End Sub

Mimic radiobuttons in datagridview using DataGridViewCheckBoxColumns

PLEASE NOTE: this question is about DataGridViewCheckBoxColumns inside a DataGridView control - not the normal CheckBox control.
I have a winforms app that contains a DataGridView with three checkbox (DataGridViewCheckBoxColumn) columns. I'd like to mimic radiobuttons ie. one, and only one, checkbox is checked at a time. I am able to turn off the other checkboxes in the grid when one is clicked as follows:
Private Sub dgvNormalReports_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles dgvNormalReports.CellClick
If mblnSuppressUI Then Exit Sub
mblnSuppressUI = True
If e.ColumnIndex >= 0 And e.ColumnIndex <= dgvNormalReports.ColumnCount - 1 And e.RowIndex >= 0 And e.RowIndex <= dgvNormalReports.Rows.Count - 1 Then
Select Case dgvNormalReports.Columns(e.ColumnIndex).Name
Case "dclLeaveOnThisList", "dclPrintLetter", "dclNoLetterNeeded" 'mimic radiobutton - turn off other checkboxes
dgvNormalReports.Rows(e.RowIndex).Cells("dclLeaveOnThisList").Value = False
dgvNormalReports.Rows(e.RowIndex).Cells("dclPrintLetter").Value = False
dgvNormalReports.Rows(e.RowIndex).Cells("dclNoLetterNeeded").Value = False
'N.B. current cell's checked status is changed AFTER this event
Case Else
'ignore
End Select
End If
mblnSuppressUI = False
End Sub
The problem I am having is that if the user clicks on a checkbox that is already checked, it becomes unchecked, and then none of the three checkboxes are checked. I always want one (and only one) checkbox ticked at all times.
Use CurrentCellDirtyStateChanged event handler.
Private Sub dgvNormalReports_CurrentCellDirtyStateChanged(sender As Object, e As EventArgs) Handles dgvNormalReports.CurrentCellDirtyStateChanged
If Me.dgvNormalReports.IsCurrentCellDirty = True Then
If Me.dgvNormalReports.CurrentCell.OwningColumn.GetType() = GetType(DataGridViewCheckBoxColumn) Then
If Me.dgvNormalReports.CurrentCell.Value = False Then
'Update only if changed from false to true
If Me.dgvNormalReports.CurrentCell.OwningColumn.Name.Equals("dclLeaveOnThisList") = false Then Me.dgvNormalReports.CurrentRow.Cells("dclLeaveOnThisList").Value = False
If Me.dgvNormalReports.CurrentCell.OwningColumn.Name.Equals("dclPrintLetter") = false Then Me.dgvNormalReports.CurrentRow.Cells("dclPrintLetter").Value = False
If Me.dgvNormalReports.CurrentCell.OwningColumn.Name.Equals("dclNoLetterNeeded") = false Then Me.dgvNormalReports.CurrentRow.Cells("dclNoLetterNeeded").Value = False
Me.dgvNormalReports.CommitEdit(DataGridViewDataErrorContexts.Commit)
Else
'Prevent changes
Me.dgvNormalReports.CancelEdit()
End If
End If
End If
End Sub
If you have predefined columns in datagridview, then may be better will be used a generated by VisualStudio column objects:
Me.dclLeaveOnThisList.Name
Me.dclPrintLetter.Name
Me.dclNoLetterNeeded.Name
First step, edit your three DataGridView columns and set each columns property ReadOnly to true (this will prevent user from changing the values)
dclLeaveOnThisList
dclPrintLetter
dclNoLetterNeeded
and second, use the following code below
Private Sub dgvNormalReports_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles dgvNormalReports.CellClick
If mblnSuppressUI Then Exit Sub
mblnSuppressUI = True
If e.ColumnIndex >= 0 And e.ColumnIndex <= dgvNormalReports.ColumnCount - 1 And e.RowIndex >= 0 And e.RowIndex <= dgvNormalReports.Rows.Count - 1 Then
Dim tmpColName As String = dgvNormalReports.Columns(e.ColumnIndex).Name
With dgvNormalReports.Rows(e.RowIndex)
Select Case tmpColName
Case "dclLeaveOnThisList", "dclPrintLetter", "dclNoLetterNeeded" 'mimic radiobutton - turn off other checkboxes
'Unchecked all checkboxes besides the selected one
If tmpColName <> "dclLeaveOnThisList" Then .Cells("dclLeaveOnThisList").Value = False
If tmpColName <> "dclPrintLetter" Then .Cells("dclPrintLetter").Value = False
If tmpColName <> "dclNoLetterNeeded" Then .Cells("dclNoLetterNeeded").Value = False
'Ensures that the selected cell is checked
.Cells(e.ColumnIndex).Value = True
End Select
End With
End If
mblnSuppressUI = False
End Sub
You can use a combination of these DataGridView events:
CellValueChanged
CurrentCellDirtyStateChanged
CellBeginEdit
You can use CellValueChanged instead of CellClick because CellClick event occurs when any part of a cell is clicked, including borders and padding (MSDN).
CurrentCellDirtyStateChanged event commit the change when the CheckBox is clicked.
The code in CellBeginEdit prevents user from modify a checked CheckBox.
This is an example:
Private Sub DataGridView1_CellValueChanged(sender As Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellValueChanged
With Me.DataGridView1
.CurrentCell.Value = True
If .Columns(e.ColumnIndex).Name = "dgvchkOptionA" Then
.Rows(e.RowIndex).Cells("dgvchkOptionB").Value = False
.Rows(e.RowIndex).Cells("dgvchkOptionC").Value = False
ElseIf .Columns(e.ColumnIndex).Name = "dgvchkOptionB" Then
.Rows(e.RowIndex).Cells("dgvchkOptionA").Value = False
.Rows(e.RowIndex).Cells("dgvchkOptionC").Value = False
ElseIf .Columns(e.ColumnIndex).Name = "dgvchkOptionC" Then
.Rows(e.RowIndex).Cells("dgvchkOptionA").Value = False
.Rows(e.RowIndex).Cells("dgvchkOptionB").Value = False
End If
End With
End Sub
Private Sub DataGridView1_CurrentCellDirtyStateChanged(sender As Object, e As System.EventArgs) Handles DataGridView1.CurrentCellDirtyStateChanged
If Me.DataGridView1.IsCurrentCellDirty Then
DataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit)
End If
End Sub
Private Sub DataGridView1_CellBeginEdit(sender As Object, e As System.Windows.Forms.DataGridViewCellCancelEventArgs) Handles DataGridView1.CellBeginEdit
With Me.DataGridView1
If .CurrentCell Is .Rows(e.RowIndex).Cells(e.ColumnIndex) And _
.CurrentCell.Value Then e.Cancel = True
End With
End Sub

looking for a way to re enable labels without specifying which ones vb.net

I am looking for a way, if its even possible, to re enable a label without actually needing to use its label name?
I have a game with labels I am using as click able boxes. The first box becomes disabled after the click event occurs, I want after the second box is clicked to re enable that first box. Any Ideas? Here is the code for the first two box click events.
Edit: there will be 15 labels, 2 can be chosen at a time. The first will be disabled so that it can't be chosen a second time.
Private Sub lblMemory1_Click(sender As Object, e As EventArgs) Handles lblMemory1.Click
Dim intClickBox As Integer = 1
Dim intClickAnswer As Integer
intClickAnswer = GuessClick(intClickBox)
If blnActive = False Then
blnActive = True
whatClicked1 = intClickBox
lblMemory1.BackColor = Color.Green
lblMemory1.Text = intClickAnswer.ToString
lblMemory1.Refresh()
System.Threading.Thread.Sleep(2000)
lblMemory1.BackColor = Color.Cyan
lblMemory1.Text = "X"
lblMemory1.Enabled = False
End If
If blnActive = True Then
whatClicked2 = intClickBox
lblMemory1.BackColor = Color.Green
lblMemory1.Text = intClickAnswer.ToString
lblMemory1.Refresh()
System.Threading.Thread.Sleep(2000)
lblMemory1.BackColor = Color.Cyan
lblMemory1.Text = "X"
blnActive = False
End If
End Sub
Private Sub lblMemory2_Click(sender As Object, e As EventArgs) Handles lblMemory2.Click
Dim intClickBox As Integer = 2
Dim intClickAnswer As Integer
intClickAnswer = GuessClick(intClickBox)
If blnActive = False Then
blnActive = True
whatClicked1 = intClickBox
lblMemory2.BackColor = Color.Green
lblMemory2.Text = intClickAnswer.ToString
lblMemory2.Refresh()
System.Threading.Thread.Sleep(2000)
lblMemory2.BackColor = Color.Cyan
lblMemory2.Text = "X"
lblMemory2.Enabled = False
End If
If blnActive = True Then
whatClicked2 = intClickBox
lblMemory2.BackColor = Color.Green
lblMemory2.Text = intClickAnswer.ToString
lblMemory2.Refresh()
System.Threading.Thread.Sleep(2000)
lblMemory2.BackColor = Color.Cyan
lblMemory2.Text = "X"
blnActive = False
End If
End Sub
you can do something like
Public Sub game(sender As Object)
Dim lbl As Label = sender
If lbl.Enabled Then
For i = 0 To Me.Controls.Count - 1
Dim lbl2 As Label = Me.Controls(i)
If Not (lbl2.Enabled) Then
lbl2.Enabled = True
GoTo exitLoop
End If
Next
End If
exitLoop:
lbl.Enabled = False
End Sub
then in each label just call the game sub and pass sender like so...
Private Sub Label1_Click(sender As System.Object, e As System.EventArgs) Handles Label1.Click
game(sender)
End Sub
this will allow only 1 label to be diabled at any give time...
you can also (within the loops) use lbl and lbl2 to set the properties for each label.
if you use a var to save the name of the first textbox you can also specifically re-enable only that box...
let me know if you want the code for that too.

How to capture arrow keys in datagridview cell end edit in VB.net

Here is my code for Cell End Edit and Selection Changed event:
Private Sub dvJOBranch_CellEndEdit(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dvJOBranch.CellEndEdit
'get the current column and row index
curCol = e.ColumnIndex
curRow = e.RowIndex
'if the cell is blank, set it to zero
If IsDBNull(dvJOBranch.Rows(curRow).Cells.Item(curCol).Value) Then
dvJOBranch.Rows(curRow).Cells.Item(curCol).Value = 0
'convert it to integer
Else
dvJOBranch.Rows(curRow).Cells.Item(curCol).Value = _
Convert.ToInt32(dvJOBranch.Rows(curRow).Cells.Item(curCol).Value.ToString())
End If
'if the user do mouseclick in datagridview
isMouseClick = dvJOBranch.Capture.ToString()
'if the user does not click any cell from the datagridview
If isMouseClick = False Then
isEdited = True
iColumnindex = e.ColumnIndex
irowindex = e.RowIndex
If dvJOBranch.CurrentRow.Index = dvJOBranch.RowCount - 1 Then
If dvJOBranch.CurrentCell.ColumnIndex < dvJOBranch.ColumnCount - 1 Then
dvJOBranch.CurrentCell = dvJOBranch.Item(iColumnindex + 1, irowindex)
End If
isEdited = False
End If
End If
End Sub
Private Sub dvJOBranch_SelectionChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles dvJOBranch.SelectionChanged
'if the user does not click any cell from the datagridview
If isMouseClick = False Then
If isEdited Then
If dvJOBranch.CurrentCell.ColumnIndex < dvJOBranch.ColumnCount - 1 Then
dvJOBranch.CurrentCell = dvJOBranch.Item(iColumnindex + 1, irowindex)
Else
dvJOBranch.CurrentCell = dvJOBranch.Item(2, irowindex + 1)
End If
isEdited = False
End If
End If
'set it to false
isMouseClick = False
End Sub
The function of this code is to move the current cell to the right after editing using ENTER key, In my code I also capture the mouse click if the user click any cell because it has errors If i do not capture the mouse click, What I'm trying to do now is to capture the Arrow keys while I'm editing. Because after editing a cell, for example when I press Arrow key UP, it moves to the right like the Function for my ENTER key instead of moving upward.
Any help and guide will be appreciated, Thank you
You could be using the KeyUp event of the datagridview like this :
Private Sub dvJOBranch(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles dvJOBranch.KeyUp
If e.KeyCode = Keys.Up Then
' Do your code here
End If
End Sub
And if you want the enter key to be handled in there you could just use a select case also :
Private Sub dvJOBranch(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles dvJOBranch.KeyUp
Select Case e.KeyCode
Case Keys.Enter
' Code for enter
Case Keys.Up
' Code for up arrow
'Etc
End Select
End Sub