I have a text box in which i don't want decimal, so I am restricting user to key in decimal by checking in keydown event.
However, this is causing issue with ">" sign as user is not able to enter ">" sign in text box.
If Not e.Handled AndAlso e.Key = Key.Decimal OrElse e.PlatformKeyCode = 190 OrElse e.PlatformKeyCode = 110 Then
If e.Key <> Key.Back Then
e.Handled = True
End If
End If
Any inputs how can i solve?
Related
I've put together a form in which a user can dynamically generate a customer order with one or more order positions. For each position, there are several attributes like amount, product name, price, discount etc.
My main problem is: What is the best way to deal with invalid values for the input fields? For example if a user types "X" into the amount field instead of 1, 2 or whatever.
The basic idea was to let the user enter everything they want - but the order can only be saved once every input field contains valid data. If not, all invalid fields will be highlighted so the user knows what he did wrong.
So far, this seems to work just fine but my idea was to also have a Customer_Order object which would be updated everytime the user changes the value of an input field.
Obviously I could not do that if I want to allow the user to enter Strings like "X" into Integer or Decimal fields... so it seems to me that I have 2 options:
A: Either restrict the input fields and programatically turn invalid values into zeros (For example: User enters "abc" into price field -> String will be converted to 0,00)
OR B: keep my original plan with not so strict input regulations and NOT have a Customer_Order object that is always kept up to date. I would instead create the object from scratch and fill it with all the data from the input fields when the user finishes the order.
My problem with A is that I would like to keep the input fields as non-strict as possible. If a user types in something invalid, they should SEE what they typed in instead of the program changing the value. And my problem with B is that having an always up-to-date object of the customer order makes it easier to calulate prices on the fly. If I don't have that object, I would have to read out and parse all the necessary input fields every time I want to calculate something.
I'm not that experienced with GUIs so I really don't know if I'm missing something here... what would be the most elegant way to handle this? Is it generally a bad idea to have an always up-to-date object in the background at all times?
One option is to only allow valid keys. This can be done by utilizing the KeyDown event handler.
Create a new Windows Forms App (.NET Framework) project
Add a TextBox to the form (name: textBoxAmount)
Open Solution Explorer
In VS menu, click View
Select Solution Explorer
Open Properties Window
In VS menu, click View
Select Properties Window
Add TextBox KeyDown event handler
In Properties Window, select textBoxAmount from the drop-down
Click
Double-click KeyDown
Add module (name: HelperInput.vb)
Click Project
Select Add Module... (name: HelperInput.vb)
Click OK
HelperInput.vb:
Imports System.Globalization
Module HelperInput
Public Sub TBKeyDownMonetaryValue(sender As Object, e As System.Windows.Forms.KeyEventArgs)
Dim tb As Control = DirectCast(sender, Control) 'TextBox
Dim isKeyAllowed As Boolean = False
Dim nfInfo As NumberFormatInfo = CultureInfo.CurrentUICulture.NumberFormat
Debug.WriteLine($"currency symbol: {nfInfo.CurrencySymbol} decimal separator: {nfInfo.CurrencyDecimalSeparator} number group separator: {nfInfo.NumberGroupSeparator} currency group separator: {nfInfo.CurrencyGroupSeparator}")
If Not Control.ModifierKeys = Keys.Shift Then
Select Case e.KeyCode
Case Keys.Enter
isKeyAllowed = True
Case Keys.Back
isKeyAllowed = True
Case Keys.Delete
isKeyAllowed = True
Case Keys.NumPad0
isKeyAllowed = True
Case Keys.NumPad1
isKeyAllowed = True
Case Keys.NumPad2
isKeyAllowed = True
Case Keys.NumPad3
isKeyAllowed = True
Case Keys.NumPad4
isKeyAllowed = True
Case Keys.NumPad5
isKeyAllowed = True
Case Keys.NumPad6
isKeyAllowed = True
Case Keys.NumPad7
isKeyAllowed = True
Case Keys.NumPad8
isKeyAllowed = True
Case Keys.NumPad9
isKeyAllowed = True
Case Keys.D0
isKeyAllowed = True
Case Keys.D1
isKeyAllowed = True
Case Keys.D2
isKeyAllowed = True
Case Keys.D3
isKeyAllowed = True
Case Keys.D4
isKeyAllowed = True
Case Keys.D5
isKeyAllowed = True
Case Keys.D6
isKeyAllowed = True
Case Keys.D7
isKeyAllowed = True
Case Keys.D8
isKeyAllowed = True
Case Keys.D9
isKeyAllowed = True
Case Else
isKeyAllowed = False
End Select
End If
'only allow one currency decimal separator
If e.KeyCode = Keys.Oemcomma AndAlso nfInfo.CurrencyDecimalSeparator = "," AndAlso (String.IsNullOrEmpty(tb.Text) OrElse Not tb.Text.Contains(nfInfo.CurrencyDecimalSeparator)) Then
isKeyAllowed = True
ElseIf e.KeyCode = Keys.OemPeriod AndAlso nfInfo.CurrencyDecimalSeparator = "." AndAlso (String.IsNullOrEmpty(tb.Text) OrElse Not tb.Text.Contains(nfInfo.CurrencyDecimalSeparator)) Then
isKeyAllowed = True
End If
If Not isKeyAllowed Then
e.Handled = True
e.SuppressKeyPress = True
End If
End Sub
End Module
Form1.vb:
Public Class Form1
Private Sub TextBoxAmount_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBoxAmount.KeyDown
HelperInput.TBKeyDownMonetaryValue(sender, e)
End Sub
End Class
Resources:
NumberFormatInfo Class
I want my program to check whether the inputs in a TextBox meet certain condition. If the target condition is not met, the cursor should focus back on that particular TextBox.
My code:
Private Sub ButtonSubmit_Click(sender As Object, e As EventArgs) Handles ButtonSubmit.Click
EnterVotes.LabelCan1.Text = CandName1.Text
EnterVotes.Labelcan2.Text = CandName2.Text
EnterVotes.LabelCan3.Text = CandName3.Text
EnterVotes.LabelCan4.Text = CandName4.Text
EnterVotes.LabelCan5.Text = CandName5.Text
If CandName1.Text = "" Then
MessageBox.Show("Please enter a name in Candidate 1")
End If
loading.Show()
Me.Hide()
If CandName1.Text = "" Then //Show your message here // CandName1.focus()//to return to that textbox Else //Show your
message here End If
use the method focus() to return and re-write into that textbox
It is actually quite simple
just check if the value of the text is > 1
then put focus on the textbox
heres an example
if txtbox.text.value < 1 then
messagebox.show("You must enter data for textbox")
txtbox.focus()
end if
and then continue method for each text box you are working with
Could get fancy and use some linq to go threw your names.
Dim Candidate() As TextBox
Candidate = Me.Controls.OfType(Of TextBox)().Where(Function(c) c.Name.Contains("CandName")).ToArray()
Dim i As Integer = 0
While i < Candidate.Count
If(Candidate(i).text.value < 1)
MessageBox.Show("Please enter a name in Candidate " & (i + 1).ToString())
Candidate(i).Focus()
Exit While
End If
i += 1
End While
This way you can check all your candidates in one shot. This is untested code, but I think it should work.
You can play around with this and edit however you please it's pretty flexible at this point.
I think this might be the way but not very efficient.
If CandName1.Text = "" Then
MessageBox.Show("Please enter a name in Candidate 1")
CandName1.Focus()
Else
CandName2.Focus()
End If
If CandName2.Text = "" Then
MessageBox.Show("Please enter an name in Candidate 2")
CandName3.Focus()
Else
CandName3.Focus()
End If
If CandName3.Text = "" Then
MessageBox.Show("Please enter a name in Candidate 3")
CandName3.Focus()
Else
CandName4.Focus()
End If
If CandName4.Text = "" Then
MessageBox.Show("Please enter a name in candidate 4")
CandName4.Focus()
Else
CandName5.Focus()
End If
If CandName5.Text = "" Then
MessageBox.Show("Pleae enter a name in candidat 5")
CandName5.Focus()
Else
loading.Show()
End If
If String.IsNullOrWhitespace( CandName1.Text ) Then
MessageBox.Show("Please enter a name in Candidate 1")
CandName1.Focus()
Return
End If
... for all five
loading.Show()
Me.Hide()
You want to make sure to exit this early with the Return statements so you don't get to the code:
loading.Show()
Me.Hide()
How would I go about making sure that when a user inputs his "Combination" into the input box, it has to be at least 5 characters?
This is what code I have so far:
If (tboxStatus.Text) = "Combination Not Set" Or (tboxStatus.Text) = "UnLocked" Then
Combination = CInt(InputBox("Set the Combination First"))
tboxStatus.Text = "Locked"
ElseIf (tboxStatus.Text) = "Locked" Then
MsgBox("You must first UnLock the safe before trying to change the combination.")
End If
For starters...
Dim value as String = InputBox("Set the Combination First")
If (value.Trim.Length < 5) Then
MsgBox ("Combination must be at least 5 characters")
Else
Combination = CInt(value)
End If
Among other things, you'll need to check if it's numeric before doing a CInt()
If tboxStatus.Text = "Combination Not Set" OrElse tboxStatus.Text = "UnLocked" Then
Dim result As String = ""
While String.IsNullOrWhiteSpace(result) OrElse Not Integer.TryParse(result, Combination)
result= InputBox("Set a Combination Number First")
End While
tboxStatus.Text = "Locked"
ElseIf tboxStatus.Text = "Locked" Then
MsgBox("You must first UnLock the safe before trying to change the combination.")
End If
I have various input textboxes on my form. And based on entries made in each of the input textboxes, I update the display textbox. However, using AppendText message of textbox. I have my input textboxes set to accept only numeric values. So for each character inputted correctly, I update the display Textbox. Problem I have is when user selects Key.Back or Key.Delete, what I would like to do is do a Delete of last character in the display textbox, but I am yet to get this right. How do I delete the last character in the string that is contained in a TextBox using AppendText() or any of the utility functions available in that control please?
If (e.KeyChar = ChrW(Keys.Back)) Then
txtDisplay.Text -= 1
txtDisplay.Update()
ElseIf (Not (Char.IsDigit(e.KeyChar) Or Char.IsControl(e.KeyChar) Or (e.KeyChar = "."))) Then
e.Handled = True
Else
txtDisplay.AppendText(e.KeyChar)
End If
Use this in KeypPress event handler of txtDisplay
If e.KeyChar = ChrW(Keys.Back) Then
If txtDisplay.Text.Length > 0 Then
txtDisplay.Text = txtDisplay.Text.Substring(0, txtDisplay.TextLength - 1)
txtDisplay.SelectionStart = txtDisplay.Text.Length
End If
ElseIf (Not (Char.IsDigit(e.KeyChar) Or Char.IsControl(e.KeyChar) Or (e.KeyChar = "."))) Then
e.Handled = True
End If
Below is the code I am using to restrict user from entering any other characters except for the predefined ones. But using my code I cannot hit backspace.
How to include backspace also ?
Dim s As String = "0123456789$"
If s.IndexOf(e.KeyChar) = -1 Then
e.Handled = True
End If
a fine list of the Keys Enumeration
Keys.Back
like:
If e.KeyCode <> Keys.Back Then
.......
End If
ControlChars.Back should give you the backspace character.
as per previous posts:
Dim s As String = "0123456789$" & ControlChars.Back
If s.IndexOf(e.KeyChar) = -1 Then
e.Handled = True
End If