Textbox search accented characters problem? - vb.net

I am looking for information on datagrid using textbox assign textchanged_event.
The problem I encountered was that when I typed the characters with a accented then datagrid would blink (it seems every change would be recorded in the textbox not just the final result).
Example: when typing "khang"
If I continue to type the letter "a", in english it will result in "khanga" and everything goes well, but in some languages it should be "khâng" and I see in textchanged it will take many steps as:
"khang" -> "khang•" -> "khang" -> "khan" -> "kha" -> "khâ" ->"khân"->"khâng"
in this moment, the datagrid will blink continuously.
what should I do to textchanged only handle the final result?
Thanks for advices!

You can't guarantee that you only handle the final value unless you use a Button.Click instead of a TextBox.TextChanged, or maybe force the user to hit Enter and handle the TextBox.KeyDown or the like. What you can do instead is ensure that you only act on the TextChanged if no other TextChanged has occurred for a specific length of time by using a Timer. That way, the delay is not so great that the user really feels it but it is long enough to allow multiple keystrokes without acting on them in between.
Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
'Start/restart the Timer every time the Text changes.
Timer1.Stop()
Timer1.Start()
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
'Perform filter when time expires.
Timer1.Stop()
BindingSource1.Filter = $"SomeColumn LIKE '%{TextBox1.Text}%'"
End Sub
It's up to you want you set the Interval of the Timer to but I'd be looking at around 300. You can do a bit of experimentation to find what gives you the best balance.

Related

Visual Basic GUI Input Validation

I took an entry level computer programming class this past term and I'm having problems with my final project. I have to design a program in visual basic GUI that asks the player to accurately guess a number between 1-100 within a limited number of guesses.
My first form asks the user to set the number of guesses allowed. It has one textbox and an "enter" button, among other buttons that I've gotten to work.
I'm trying to get code to work that will validate the input on the guesses allowed. Specifically, I want a message box to pop up if the player enters letters or special characters instead of numbers, or enters a number less than zero, or greater than twenty. Here's what I have:
Public Class Noofguesses
Shared maxguesscnt As Integer
Private Sub Numberofguesses_TextChanged(sender As Object, e As EventArgs) Handles Numberofguesses.TextChanged
End Sub
Private Sub Quit_Click(sender As Object, e As EventArgs) Handles Quit.Click
End
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Form3.Show()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If Val(Numberofguesses) > 20 Then MsgBox("Number of Guesses Cannot Exceed 20")
If Val(Numberofguesses) < 0 Then MsgBox("Number of Guesses Must Be Greater Than 0")
If Not IsNumeric(Numberofguesses) Then MsgBox("Entry Cannot be Letters or Characters")
Me.Close()
Form2.Show()
End Sub
End Class
What am I doing wrong? Please let me know.
Thanks
I would generally suggest using a NumericUpDown rather than a TextBox, in which case no validation is required. As this is an assignment though, I'm guessing that validating a TextBox is a requirement. In that case, you should use Integer.TryParse to validate a String, i.e. the Text of the TextBox and convert it if it is valid. You can then test the converted value to make sure that it isn't less than zero, etc. I'm not going to write the code for you, given that this is homework, but that should be enough for you to do it yourself or, if you feel you must, find examples online.

How do I make a textbox read only using code when an event happens in VB?

I've made a program in VB where the user selects from a drop down box whether they would like to find out speed, distance or time. There are three textboxes on the form where the user can enter speed, distance and time, and they don't enter anything for the one which they want to find out.
When the user chooses to find out speed, I want the speed textbox to be changed to read only, when the user chooses to find out distance, I want that textbox to be changed to read only, etc.
Thanks in advance.
You can make a Textbox read only by using the following code:
textbox1.ReadOnly = true
You can also found out more here.
Handle the SelectedIndexChanged event and set the Enabled property in there.
Private Sub ComboBox1_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
Me.TextBoxSpeed.Enabled = ComboBox1.SelectedItem <> "Speed"
Me.TextBoxTime.Enabled = ComboBox1.SelectedItem <> "Time"
Me.TextBoxDistance.Enabled = ComboBox1.SelectedItem <> "Distance"
End Sub

VB.net SendKeys to send keys combined not using "ALT" or "CTRL", like "{INS}(S)"

I need to send the keystroke combination INSERT + S keys simultaneously but it seems that VB only leaves use key combinations with ALT, CTRL and SHIFT.
Is there any way to do it?
I've tried:
{INS}(S)
{INS}S
and many others, but this does not work.
Thanks a lot.
It does. See:
https://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
Had you tried "{INS}(S)" ?
UPDATE
I did the following test:
Private Sub TextBox1_Click(sender As Object, e As EventArgs) Handles TextBox1.Click
SendKeys.Send("{Ins}S")
End Sub
Private Sub TextBox1_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox1.KeyDown
MsgBox(e.KeyCode)
End Sub
Look, I received in the KeyDown event 2 codes: the INS and the "S"
The problem is about the KeyDown event will file TWO TIMES, I mean, you cannot get the INS-S code with ONE reading.
So, you must consider have a FRIEND/PUBLIC variable to receive both codes and only after this, make the critic about these.
Good luck

Delay textbox-textchanged in vb

I am a simple beginner and need small help:
I have textbox1 and textbox2.
Supposed when you put a number (for ex. 21) in the textbox1, I need textbox2 to give me the double number (42). I mean that I need textbox2.text=2*textbox1.text
I used this simple code :
Private Sub TextBox1_Textlength(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles TextBox1.TextChanged
TextBox2.Text = 2*TextBox1.Text
The problem is: when I wrote (in textbo1) only one digit everything it's ok, but I could not write two (or more) digits.
How do I make a delay (interval) which allows me to type a number like (1990 for example) before firing textbox1_changed?
TextChanged fires every time you change the content of the textbox. So there is no way to block this behavior. Perhaps you could add a button and move the recalculation on the button click event or better add an event handler for the Validating event.
This event is triggered when you exit from the control and you have also the option to check the input and block the exiting from the TextBox control
Private Sub textBox1_Validating(ByVal sender As Object, _
ByVal e As System.ComponentModel.CancelEventArgs) Handles TextBox1.Validating
Dim v as Integer
if Not Int32.TryParse(TextBox1.Text, v) Then
e.Cancel = True
MessageBox.Show("Please type a valid number")
Else
TextBox2.Text = (v * 2).ToString
End If
End Sub
Notice that when you handle the user input expecting a numeric value you should apply particular attention because you don't know what the user types. In this case the Int32.TryParse seems to be the appropriate approach.
Another suggestion is to enable immediately the Option Strict ON in your project, the default is OFF and this allows very dangerous code like treating a string like it was a number.
You don't need to. Just allow the TextChanged event to fire every time, and the second text box will always display twice the value of the first one, so when 1 is entered, it will show 2, when the 9 is added, it will show 38, and so on. You should of course address Steve's concerns about validation, and implied type conversions.

How to retain contents of datagrid view when applying multiple filters

I am trying to provide my users a nice search capability. I want to do so using textboxes to filter a datagridview. I have a dgv containing all animals in the database. For simplicity sake let’s say the first two columns are animalName and animal (dog or cat). I have two textboxes used for filtering, one for each of those two columns. Let's say I want to find all dogs named Buddy. In my first text box I type 'Buddy' and, because of the filter code behind the textbox change event the dgv now contains only the Buddys. When I go to textboxAnimal and type 'd' for dog the dgv changes to show all the dogs; not just the ones named Buddy. How can I make it such that the results of the first filter stay in place when I apply the second filter?
I assume I need to use the lostFocus (or gotFocus or leave) event of the first textbox but just don’t know what code to put behind it. I guess I could hard code a select statement that would then be used to repopulate the datagridview but this could get onerous as I’m going to have many textboxes; not just two.
Any help would be greatly appreciated.
Focus is irrelevant. You handle the TextChanged event of both TextBox controls and you build the filter from scratch every time, taking both fields into account, e.g.
Private Sub TextBoxes_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged,
TextBox2.TextChanged
Me.BindingSource1.Filter = String.Format("Column1 LIKE '%{0}%' AND Column2 LIKE '%{1}%'",
TextBox1.Text,
TextBox2.Text)
End Sub
One pitfall of filtering on TextChanged, regardless of how many fields you're filtering on, is that you will end up filtering needlessly several times when the user types several letters. For instance, if the user intends to type "bud" then there's no point to filtering after the "b" and the "bu" and it may actually degrade performance if the data set is large. For that reason, it's nice to use a Timer to delay filtering for a short period. That will defer filtering until the user stops typing in most cases. You can play with the Interval to get the performance you want. Probably about 500 ms should do it but it's up to you.
Private Sub TextBoxes_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged,
TextBox2.TextChanged
'Start or restart the timer because the user typed something.
Me.Timer1.Stop()
Me.Timer1.Start()
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
'The timer has expired so the user has not typed anything for the prescribed amount of time.
Me.BindingSource1.Filter = String.Format("Column1 LIKE '%{0}%' AND Column2 LIKE '%{1}%'",
TextBox1.Text,
TextBox2.Text)
End Sub