How to force text being entered into a textbox into Uppercase? - vb.net

I want to make the text that a user is typing into a textbox become uppercase. I know two ways to do this, which are:
Textbox1.Text = UCase(Textbox1.Text)
or
Textbox1.Text = Textbox1.Text.ToUpper
HOWEVER: both have the same problem (when embedded in a Textbox1_TextChanged event handler), which is that the cursor keeps being moved back to the start, so if you slowly type in, say abcdef, it comes out as FEDCBA. Is there a way to move the cursor back to the end of the string after each time it works to make the text uppercase?

go to textbox property, change CharacterCasing to Upper

Use the KeyPress event to detect lower case letters being entered, and convert them to uppercase as you go:
Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
If KeyAscii > 96 And KeyAscii < 123 Then
'Typed letter from "a-z", map it to "A-Z"
KeyAscii = KeyAscii - 32
End If
End Sub
Ucase() is used only after the person is done entering the text.
If you are using VB.NET then you just need to set the .CharacterCasing property of the TextBox to .Upper - No code needed. But if you wanted to use code for some reason, use this:
TextBox1.CharacterCasing = CharacterCasing.Upper

Why don't you just place the code Textbox1.Text = Textbox1.Text.ToUpper in the Textbox1_LostFocus event instead of the Textbox1_TextChanged event. It's so simple and it works even if you paste text into the field. As soon as your cursor moves to another field, the event is triggered, causing the text to change case from lower to upper.

You could also use:
Private Sub Textbox1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles Textbox1.KeyPress
e.KeyChar = UCase(e.KeyChar)
End Sub
... if you need to do some custom formatting or logic. Otherwise I'd also suggest using the default TextBox property CharacterCasing set to Upper.
Please note that this solution does not handle the situation when user is pasting text into the TextBox component and you have to programmatically take care of that situation too if needed, but the TextBox property CharacterCasing does it for you even if user is pasting text into the component.

Your version didn't quite work for me in Visual Basic 2019, but it formed the basis of this, which does (where "txtPrem1" is the TextBox):
Private Sub txtPrem1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles txtPrem1.KeyPress
Dim KeyAscii = AscW(e.KeyChar)
If KeyAscii > 96 And KeyAscii < 123 Then
'Typed letter from "a-z", map it to "A-Z"
KeyAscii = KeyAscii - 32
End If
e.KeyChar = ChrW(KeyAscii)
End Sub

How about this:
Private Sub MyText_TextChanged(sender As Object, e As EventArgs) _
Handles MyText.TextChanged
Dim oText As TextBox = CType(sender, TextBox)
oText.Text = oText.Text.ToUpper
oText.SelectionStart = oText.Text.Length
oText.SelectionLength = 0
End Sub

Related

Data Type validation in textbox

Trying to make a validation where only letters can be entered into a textbox. I've got that part working, but I would also like the ability for the user to use the backspace button, and I'm not sure how
Private Sub TxtBoxCustForename_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TxtBoxCustForename.KeyPress
If Asc(e.KeyChar) < 65 Or Asc(e.KeyChar) > 122 Then 'Ensures only letters can be entered by using the ASCII converter'
e.Handled = True
MessageBox.Show("You may only input letters")
End If
End Sub
Input validation is a built-in feature of .NET. You don't need to capture key presses and manually code your own solution.
You might want to use a MaskedTextBox as suggested in this article:
https://learn.microsoft.com/en-us/dotnet/framework/winforms/user-input-validation-in-windows-forms
You can change your If statement like this:
If (Asc(e.KeyChar) < 65 Or Asc(e.KeyChar) > 122) And Asc(e.KeyChar) <> 8 Then
Ascii 8 is the Backspace key.
Rather than using the KeyPress event, use the TextChanged event. Also, I would recommend using the IsNumeric function to test whether it is a number or not.
Private Sub TxtBoxCustForename_KeyPress(sender As Object, e As EventArgs) Handles TxtBoxCustForename.TextChanged
For Each entry as Char in TxtBoxCustForename.Text
If IsNumeric(entry) Then
MessageBox.Show("You may only input letters")
Exit For
End If
Next
End Sub
If you're going to use .NET then use .NET.
Private Sub TxtBoxCustForename_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TxtBoxCustForename.KeyPress
Dim keyChar = e.KeyChar
If Not Char.IsLetter(keyChar) AndAlso Not Char.IsControl(keyChar) Then
e.Handled = True
MessageBox.Show("You may only input letters")
End If
End Sub
This still doesn;t prevent the user pasting invalid text into the control though, so you still need to handle the Validating event or use a custom control that catches paste operations.

How can I make it so a TextBox will dynamically adjust the input as a currency format?

This app I'm designing has a TextBox named txtValue with the properties MaxLength set to 14 and TextAlign set to Right. I want txtValue to only accept currency, and dynamically format the input so the user doesn't need to add commas, only one period.
I managed to make it so txtValue will only accept numbers and one dot in the event txtValue_KeyPress.
txtValue_LostFocus will convert the input into currency format.
Here's my code so far:
Private Sub txtValue_KeyPress(sender As Object, e As KeyPressEventArgs) Handles txtValue.KeyPress
'Allows only one dot
If (e.KeyChar.ToString = ".") And (txtValue.Text.Contains(e.KeyChar.ToString)) Then
e.Handled = True
Exit Sub
End If
'Allows only 0 to 9 and dot (once)
If (e.KeyChar.ToString < "0" OrElse e.KeyChar.ToString > "9") _
AndAlso e.KeyChar <> ControlChars.Back _
AndAlso e.KeyChar.ToString <> "." Then
e.Handled = True
End If
End Sub
Private Sub txtValue_LostFocus(sender As Object, e As EventArgs) Handles txtValue.LostFocus
txtValue.Text = Format(Val(txtValue.Text), "000,000,000.00")
End Sub
I expect the input -q1w23456789012....34 to return the output 123,456,789,012.34, but the actual output after it loses focus is 123,456,789,012.30
This seems like an easy fix, like setting MaxLength to 15, but then if I don't type a period, it'll allow me to type 15 numbers and I only want up to 12 plus 2 after the period.
I expect the input -q1w234....5678 to return the output 1,234.56, but the actual output after it loses focus is 000,000,001,234.56
This seems like a more complex fix, because I don't want to use the LostFocus event to validate what I type. I want the KeyPress event to handle the input and dynamically format what I type.
In this case:
The input 1 would have the output 1.00
The input 123.4 would have the output 123.40
The input 1234.567 would have the output 1,234.56
All of this without needing the LostFocus event, but right now I'm using the LostFocus event because that's all my very limited knowledge allows me to do.
UPDATE
Alright I'm now using the Leave event, but then again I was only using LostFocus as a placeholder because in the end I want the TextBox to adjust what the user types as they type.
An alternative way to handle. For details on formating numbers for display try MS docs https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings or https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-numeric-format-strings
Private err As New ErrorProvider()
Private d As Decimal 'In case you want to use the value as a number somewhere else
Private Sub TextBox17_Validating(sender As Object, e As CancelEventArgs) Handles TextBox17.Validating
If Not Decimal.TryParse(TextBox17.Text, d) Then
e.Cancel = True
err.SetError(TextBox17, "This text box must contain a number.")
Else
err.Clear()
End If
End Sub
Private Sub TextBox17_Validated(sender As Object, e As EventArgs) Handles TextBox17.Validated
TextBox17.Text = d.ToString("C")
End Sub

VB TextBox entry handling - TAB key missing

Windows 10/VS 2015 Community/Visual Basic 2014
I have written the following to input text from 13 TextBoxes. It inputs
each character with its own event. Each character is checked for being
a valid character (numerals, letters, symbols) plus Cr (to move to next
TextBox) and BS (to permit typo corrections). This works:
'===== Enter Frequency =====
Private Sub TextBox1_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress
ichar = e.KeyChar()
ckinchar() 'ck for input characters, or CR or BS keys
If eoline = 1 Then 'has <cr> been detected?
freq = inline 'Yes
bufcnt = 0 'Reset counter
eoline = 0 'Rest EOL flag
TextBox1.BackColor = Color.LightGreen
TextBox2.BackColor = Color.LightPink
TextBox2.Focus()
Exit Sub
Else
TextBox1.Focus() 'No - repeat inputting
End If
End Sub
Problem: I wish to also use the TAB key (to be implemented as the Cr key)
However the TAB key code fails to appear. In run mode pressing the Tab key
causes the cursor to move up the displayed TextBoxs following the tabIndex order. I've tried using KeyDown/Enter/TextChanged events to no effect -
mostly problems getting implemented.
Can anyone suggest any errors I might have in first two lines, or alternative choice. Is/are there any Properties in the TextBox I should be looking at.
TIA Day Watson
Private Sub TextBox1_PreviewKeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.PreviewKeyDownEventArgs) Handles TextBox1.PreviewKeyDown
If e.KeyCode = Keys.Tab Then
Me.Text = "TAB Captured"
End If
End Sub

Toggle the masking and unmasking of a TextBox using a CheckBox

I have a TextBox, which has a CheckBox operation to mask the containing text. This works with the following code:
Private Sub CheckBox2_Checked(ByVal sender As Object, ByVal e As EventArgs) Handles CheckBox2.CheckedChanged
TextBox14.PasswordChar = "*"
End Sub
It works well, but I want to also be able to uncheck theCheckBox and then have the recognizable text return. How can I achieve this?
The docos actually state:
The character used to mask characters entered in a single-line TextBox
control. Set the value of this property to 0 (character value) if you
do not want the control to mask characters as they are typed. Equals 0
(character value) by default.
Found here: http://msdn.microsoft.com/en-us/library/system.windows.forms.textbox.passwordchar(v=vs.110).aspx
In VB.NET, that would be easiest done by setting PasswordChar to vbNullChar.
You can do so by simply setting the PasswordChar property back to a null character, like this:
Private Sub CheckBox2_CheckedChanged(ByVal sender As Object, ByVal e As EventArgs) Handles CheckBox2.CheckedChanged
If CheckBox2.Checked Then
TextBox14.PasswordChar = "*"c
Else
TextBox14.PasswordChar = ControlChars.NullChar
End If
End Sub
The CheckedChanged event occurs every time the Checked property changes. So, when the user unchecks the CheckBox, it will raise that event too, so you need to check to see whether or not the control is currently checked.
I found just toggling the password character wasn't enough. In my case I was masking a connection string. With the lack of spaces in my text I had an issue going back and forth. My text would be cut off and wasn't wrapping properly.
Private Sub CheckBox1_CheckedChanged(sender As Object, e As EventArgs)
Dim beforeText As String = TextBox1.Text
TextBox1.Text = ""
TextBox1.PasswordChar = IIf(CheckBox1.Checked, Convert.ToChar(0), "*"c)
TextBox1.Text = beforeText
End Sub
I imagine if you used a font like Console this would not be a problem as all character widths are constant.

Capture keypress / let user pick their own start/stop key

Currently I have the start-key for my vb.net application hardcoded like this:
GetAsyncKeyState(Keys.F2)
Where vb.net sais "F2 As System.Windows.Forms.Keys = 113" on mouse-over
But I want my users to be able to pick their own Key. If I make a drop-down box (combobox) and pre-define some choices in there (Like ESC or F3), all those choices are strings. How can I convert those strings to a System.Windows.Forms.Keys integer?
Also, I'd like it to also be possible to "capture" a single keypress. So they'd click the "capture" button, and the next key they hit will be saved as the start/stop button. But I wouldn't even know where to begin looking for that one.
If txtKeys.Text=="F3" Then
GetAsyncKeyState(Keys.F3)
End If
Try something like this:
Public Class Form1
Dim captureKey As Boolean
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
captureKey = True
End Sub
Private Sub Button1_PreviewKeyDown(sender As Object, e As System.Windows.Forms.PreviewKeyDownEventArgs) Handles Button1.PreviewKeyDown
If captureKey Then
Label1.Text = e.KeyValue.ToString
captureKey = False
End If
End Sub
End Class
I created a form with a label and a button for an example. e.KeyValue is an integer that I am converting to a string for display purposes. You also have the ability to capture other keydata. See this info on PreviewKeyDownEventArg
As for the first part of your question use a Select Case Statement to convert between your ComboBox Values and KeyData Values.