Validating Textboxs - vb.net

I am doing a simple aplication using Windows Forms and I have a question...
My form has 15 textboxs and I want to validate everyone using the event KeyPress or validating. I have this code that is working:
If Not IsNumeric(txtn1.Text) Then
e.Cancel = True
ErrorProvider1.SetError(txtn1, "")
Else
something(txtn1.text)
End If
But I have 15 textboxs (maybe more) and is a little humdrum copy/pase this code in every textbox event. Can you teach me to do this using a function?
Public Function isnum(ByVal txt As TextBox, ByVal errpro as ErrorProvider) As Double
If Not IsNumeric(txt.Text) Then
e.Cancel = True <-------------------------------This dont work
errpro.SetError(txt, "")
End If
End Function
Private Sub txtn1_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles txtKLDC.Validating
if isnum(txtn1, ErrorProvider1) then
something(txtn1.text)
end if
I´m looking for the correct way to do this?
English is my second language and I'm learning programming too.

Use a common KeyPress event then use the sender object which is the TextBox that originated the Event and cast it to a TextBox.
Private Sub txt_KeyPress(sender As System.Object, e As System.Windows.Forms.KeyPressEventArgs) Handles txtn1.KeyPress, txtn2.KeyPress, txtn3.KeyPress, txtn4.KeyPress, txtn5.KeyPress
Dim tb As TextBox = CType(sender, TextBox)
If Not IsNumeric(tb.Text) Then
e.Handled = True
ErrorProvider1.SetError(tb, "")
Else
something(tb.Text)
End If
End Sub

With this code:
Private Sub NumericValidation_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) _
Handles TextBox1.KeyPress, TextBox2.KeyPress, upto 16500 or so is possible...
Dim txt As TextBox = CType(sender, TextBox)
If Not IsNumeric(txt.Text) Then
e.Cancel = True
ErrorProvider1.SetError(txt, "")
Else
something(txt.text)
End If
End Sub
Notice how I assign each one of the Textbox's KeyPress Event Handler to the single NumericValidation_KeyPress sub routine. I cast the sender into a Textbox to find out which textbox keypress event fired.

Related

vb.net - enable/disable a button depending on user input

As I'm putting the finishing touches on my program I'm having some troubles.
Theres several user inputs and a submit button, once the inputs has been filled I wish to enable the submit button, else the button should be disabled. This is what I have:
Private Sub ButtonControl(sender As System.Object, e As System.EventArgs) Handles Input1.Validated
If Input1.Text = "" Then
ButtonSubmit.Enabled = False
ElseIf Input1.Text <> "" Then
ButtonSubmit.Enabled = True
End If
End Sub
The thing is it disables nomatter what and then it doesnt enable when my input is filed
Your code will work if you have another control that can receive the focus. Control Validation occurs on the loss of focus. If you need to have just one focusable item active you will need to use either KeyPress, KeyDown or Textchanged events to enable your button, also make sure that the CausesValidation property of your TextBox is true.
I would also make the method more generic so you could call it from multiple textbox's by using the sender object to access the textbox that raised the event. Also if you have a True/False condition you only need to do the comparison in the first if statement and then you just use an else not an elseif.
for example:
Private Sub ButtonControl(sender As System.Object, e As System.EventArgs) Handles Input1.Validated
If DirectCast(sender, TextBox).Text = "" Then
ButtonSubmit.Enabled = False
Else
ButtonSubmit.Enabled = True
End If
End Sub
You can also use the String.IsNullOrWhiteSpace Method to check if just spaces have been entered if you are using the 4.0 framework or above. Like this TextChanged EventHandler.
Private Sub ButtonControl(sender As Object, e As EventArgs) Handles Input1.TextChanged
If String.IsNullOrWhiteSpace(DirectCast(sender, TextBox).Text) Then
ButtonSubmit.Enabled = False
Else
ButtonSubmit.Enabled = True
End If
End Sub
You are going to need to use the TextBox "TextChanged" event, and be sure to set each Textbox AutoPostback="True". You can use an UpdatePanel to make the postbacks that occur on each Textbox you wish to validate less obnoxious to your end-user.
So, your textbox (if you have many, make sure they all have the OnTextChanged="ValidateForm":
<asp:TextBox ID="Input1" runat="server" OnTextChanged="Validate_TextChanged" />
Inside your textchanged ("ValidateForm") event (which each Textbox is attached to), one quick to implement route to do would just be
' Validation inside this event
Protected Sub Validate_TextChanged(sender As Object, e As EventArgs)
if Input1.text <> "" AndAlso Input2.text <> "" AndAlso ' ...etc.
End Sub
If you go the route of the UpdatePanel, you may find this useful.
This is the kind of thing I would do:
Private Sub TextBoxes_TextChanged( _
ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles _
TextBox1.TextChanged, _
TextBox2.TextChanged, _
TextBox3.TextChanged
Dim textBoxes = { TextBox1, TextBox2, TextBox3 }
Button1.Enabled = textBoxes.All(Function (tb) tb.Text <> "")
End Sub
You can then add as many text boxes in to the textBoxes array as you need to check. Just make sure that the text boxes to the Handles list.
Private Sub TextBox1_TextChanged(sender As System.Object, e As System.EventArgs) Handles TextBox1.TextChanged
If TextBox1.Text.Length > 0 Then
Me.Button1.Enabled = True
Else
Me.Button1.Enabled = False
End If
End Sub
Do that code in the Input1_TextChanged event
This is what I did and worked:
Dim CheckInput1 As Boolean
Private Sub Input1_TextChanged(sender As Object, e As EventArgs) Handles Input1.TextChanged, Input1.Enter
CheckInput1 = True
If Input1.Text = "" Then
CheckInput1 = False
End If
If CheckInput1 = False Then
ButtonSubmit.Enabled = False
ElseIf CheckInput1 = True Then
ButtonSubmit.Enabled = True
End If
End Sub
There must be a more efficient code that this but I think this solves your problem.

One Textbox Value Greater then other, Avoid and Beep

I have two Textboxes in Visual Basic 2010
Textbox1
Textbox2
Now I want that if user enter value(integer) in Textbox2, if the value in Textbox2 is Greater than Textbox1, so this will do a beep and also avoid him to do like this
Example: If User write 5 in Textbox1 and now he is writing 8 in Textbox2 so as 8 is grater than 5, so i want that Textbox2 ignore with a beep.
I have this code but this is not working, please if some one help me:
Private Sub TextBox2_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox2.KeyPress
Dim valx1 As Integer
Dim valx2 As Integer
valx1 = (Val(TextBox1.Text))
valx2 = (Val(TextBox2.Text))
If (valx1) > (valx2) Then
Beep()
e.Handled = True
End If
End Sub
This code will suits your requirement, By the way using a beeb sound for alerting the user, will make him/her disturbed.
Private Sub TextBox2_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox2.KeyPress
if val(TextBox1.Text.trim) > val(TextBox2.Text.trim & e.keychar) then
Beep()
e.Handled = True
end if
End Sub

sub event to interact with more than one control

I want to call this snippet passing a "controlname" like a argument, then the sub interacts with the desired control
How I can do that?
This is the snippet:
#Region " Move a control in real-time "
' Change Textbox1 to the desired control name
Private Sub TextBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles textbox1.MouseDown
If e.Button = Windows.Forms.MouseButtons.Left Then
textbox1.Capture = False
Dim ControlMoveMSG As Message = Message.Create(textbox1.Handle, &HA1, New IntPtr(2), IntPtr.Zero)
Me.DefWndProc(ControlMoveMSG)
End If
End Sub
#End Region
UPDATE:
The solution:
Private Sub MoveControl(sender As Object, e As EventArgs) Handles _
TextBox1.MouseDown, _
TextBox2.MouseDown, _
PictureBox1.MouseDown
Dim control As Control = CType(sender, Control)
control.Capture = False
Dim ControlMoveMSG As Message = Message.Create(control.Handle, &HA1, New IntPtr(2), IntPtr.Zero)
Me.DefWndProc(ControlMoveMSG)
End Sub
In this case, you can just use sender. The sender parameter is a reference to whichever control is raising the event. So, if you add this same method as an event handler for multiple controls, sender will be which ever control raised the event that it's currently handling, for instance:
Private Sub MouseDown(sender As Object, e As EventArgs) _
Handles TextBox1.MouseDown, TextBox2.MouseDown
' Note in the line above that this method handles the event
' for TextBox1 and TextBox2
Dim textBox As TextBox = CType(sender, TextBox)
' textBox will now be either TextBox1 or TextBox2, accordingly
textBox.Capture = False
' ....
End Sub
The CType statement casts the base Object parameter to the specific TextBox class. In this example, the method only handles events for TextBox objects, so that will work. However, if you have it handle events from other types of controls, you'd need to cast to the more general Control type (i.e. CType(sender, Control)).

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

How to check focused TextBox in vb.net winforms?

I have multiple textbox in a form. How do I know what textbox the cursor currently is?
Trying to do something like this:
If TextBox2.Focus() = True Then
MessageBox.Show("its in two")
ElseIf TextBox3.Focus = True Then
MessageBox.Show("its in three")
End If
But I think its not working.
TextBox.Focus actually assigns the focus to the given textbox. What you're looking for is TextBox.Focused. :)
In fact, all form controls have the Focused property.
I know this already has an accepted answer but I just think this method is a bit easier and should be up here for people who find this through Google or whatever.
Public focussedTextBox As TextBox
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
For Each control As Control In Me.Controls
If control.GetType.Equals(GetType(TextBox)) Then
Dim textBox As TextBox = control
AddHandler textBox.Enter, Sub() focussedTextBox = textBox
End If
Next
End Sub
This way you can then just refer to the focussedTextBox at any time. You should make sure that you check that there is a focussedTextBox before you do however becuase when the application first loads there will not be. You can do this using:
If Not focussedTextBox Is Nothing Then
...
End If
Alternatively, you could set focussedTextBox to a TextBox of your choice on form load, either by setting its value or by focussing the TextBox.
Obviously, it will not work if you are calling your code in a Button_Click because when you click the Button then the focus is itself goes to the Button which you have clicked.
You can do two things:
Make a combined Focus event for all TextBoxes and check its Sender object.
Private Sub TextBox_Focus(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox2.Enter, TextBox3.Enter
Dim currTextBox As TextBox = sender
If currTextBox.Equals(TextBox2) Then
MessageBox.Show("it's in two")
ElseIf currTextBox.Equals(TextBox3) Then
MessageBox.Show("it's in three")
End If
End Sub
OR
Take a global string variable, and set its value at each TextBox_Focus event, then check string value in the button click event.
Dim str As String
Private Sub TextBox2_Focus(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox2.Enter
str = "two"
End Sub
Private Sub TextBox3_Focus(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox3.Enter
str = "three"
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
MessageBox.Show("it's in " & str)
End Sub