Hi, i have an autocomplete textbox in vb.net. It is working fine, but now i need to pop up the window again when the user hits enter or double clicks.
So far, i know that when the user hits enter, the keydown event raises with e.kecode = 13. I guess my code would go here. My problem is how do i tell autocomplete to start again after the user hits enter??
Thanks in advance.
Can't you just call the auto complete code again? The last text entered is still in the text box at this point? It would just be a matter of detecting the enter key press and calling the function.
Yes, the last text entered will be in the textbox. I just don't know how to call the autocomplete code again. For example: if i start writing "user1@g" the list will appear and the text will be autocompleted "user1@gmail.com". Now if i hit the right arrow to start typing again the autocomplete will not work.
This is probably because the auto complete code is being called in the onTextChanged event and simply hitting the arrow key won't cause it to fire again (mainly because the text box doesn't have focus anymore). You can catch in the form's key event rather than that of the text box and call whatever function is called by onTextChanged function.
thecoder2012, I somewhat understand what you are asking, do correct .Me If I am wrong.:)
You have items in the AutoComplete as "12,13,14,21,23,24".
You start typing "1", of course, AutoComplete starts.
You press the Keys.Enter, and you would like to continue typing in TextBox, though have the AutoComplete."RELOAD" again and give you more options "again".
If this is on the right.path, I am not sure If the .Default AutoComplete that comes w/vb.net allows such and you might have to create your own Custom.AutoComplete.
Being a new morning for a new bright.day, I have this idea.suggestion.
.1 Add a TextBox.
2. Add a "ContextMenuStrip" and use that as your AutoComplete.
.3 Have the "ContextMenuStrip" Load/.Show with all of your AutoComplete.Items, and when you press enter, to ."re"Load/Show" w/the AutoComplete.Items from the .SubString of the TextBox, where you pressed Keys.Enter last.
Could be a fun little project to work on, thus I will let you have fun w/it and I will Challenge a mythical.history with Assasin's Creed:Revelations .:D
If .My above idea/suggestion is something you think it is possible, I especially do, do give it a Go and post results of your progress.
If Nothing or something achieved and I need to boot up vb.net, do let .Me know, of course, after you started making some progress.
Hope this helps and that the New Year will be a Challenging and Happy New Year, for you and anyone else that reads this before the end of this k"ewwll".night(12.31.o11).:)
First thing to say is, Happy new year everybody. Second, Thank you guys for all your help, but i don't have a solution yet. I've been trying all of your sugestion but nothing works yet.
Hericles, i don't know which function it's been called, i don't see any code related to the autocomplete property.
Codeorder, i played a little bit with the contexmenustrip control (and after that God of war lol), and it can be done that way. The problem is that i don't want a menu for this project. For this app, i have a form to send emails. I need the emails to appear automatically when users type. something similar hotmail or gmail.
I think the autocomplete property just work for one item. :(
I think it also works for one item, the first, which just makes programming that much more interesting for the rest of us big kids, we get bad toys to play with.:D
I'll see what I can do and will try to post something reasonable as soon as I have something reasonable. Should be no time, If Not for Assasin's Creed:Revelations:D, though almost at the end of story.:(
.k., started working on this:
1.TextBox,1.Label,1.ContextMenuStrip(toolbox:Menus & sh.t:)
Public Class Form1
Private myEmailAddresses() As String = {"abc@daniweb.com", "abc.again@daniweb.com", "bcd@daniweb.com", "bcd.again@daniweb.com"}
Private chrEmailSeparator As Char = ";"
Private WithEvents tmrCM As New Timer With {.Interval = 500, .Enabled = True}
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
With ContextMenuStrip1
'.dropdown()
End With
End Sub
Private Sub TextBox1_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyDown, ContextMenuStrip1.KeyDown
Select Case e.KeyCode
Case Keys.Down
With ContextMenuStrip1
If Not .Items.Count = 0 Then
.Select() : .Focus()
Dim iItemIndex As Integer = -1, sItemText As String = .GetItemAt(.DisplayRectangle.X, .DisplayRectangle.Y).Text
'For Each itm As ToolStripItem In .Items
' If itm.Text = sItemText Then
' iItemIndex += 1
' Exit For
' End If
'Next
TextBox1.Text = sItemText : .Select() : .Focus()
End If
End With
End Select
End Sub
Private Sub TextBox1_TextChanged(sender As System.Object, e As System.EventArgs) Handles TextBox1.TextChanged
loadCoolAutoComplete(myEmailAddresses, TextBox1, ContextMenuStrip1)
End Sub
'Private isReloaded As Boolean = True
Private Sub loadCoolAutoComplete(ByVal selEmailsCoolArray As Array, ByVal selCoolTextBox As TextBox, ByVal selContextMenu As ContextMenuStrip)
With selContextMenu
.Items.Clear()
Dim txtIndex As Integer = selCoolTextBox.GetLineFromCharIndex(selCoolTextBox.SelectionStart) - selCoolTextBox.GetFirstCharIndexFromLine(selCoolTextBox.GetLineFromCharIndex(selCoolTextBox.SelectionStart))
For Each itm As String In selEmailsCoolArray
If itm.StartsWith(selCoolTextBox.Text) Then .Items.Add(itm)
Next
'Dim sItemText As String = .GetItemAt(.DisplayRectangle.X, .DisplayRectangle.Y).Text
'TextBox1.Text = sItemText : .Select() : .Focus()
selCoolTextBox.Select(selCoolTextBox.TextLength, 0)
' If Not .Items.Count = 0 Then .Items(0).Select()
' selCoolTextBox.Text = .GetItemAt(.DisplayRectangle.X, .DisplayRectangle.Y).Text
' selCoolTextBox.Select(txtIndex, selCoolTextBox.TextLength - txtIndex)
If Not selCoolTextBox.Text = Nothing Then 'andalso Not selCoolTextBox .Text .Contains ( Then
.AutoClose = False
.Show(Me, selCoolTextBox.Location.X, selCoolTextBox.Location.Y + selCoolTextBox.Height)
If Not .Width = selCoolTextBox.Width Then .Width = selCoolTextBox.Width
Else
.AutoClose = True
.Visible = False
End If
End With
End Sub
Private Sub ContextMenuStrip1_Closing(sender As Object, e As System.Windows.Forms.ToolStripDropDownClosingEventArgs) Handles ContextMenuStrip1.Closing
tmrCM.Stop()
End Sub
Private Sub ContextMenuStrip1_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles ContextMenuStrip1.KeyDown
'With ContextMenuStrip1
' Dim sItemText As String = .GetItemAt(.DisplayRectangle.X, .DisplayRectangle.Y).Text
' Me.Text = sItemText
'End With
End Sub
Private Sub _tmrCM_Tick(sender As Object, e As System.EventArgs) Handles tmrCM.Tick
End Sub
Private Sub ContextMenuStrip1_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles ContextMenuStrip1.MouseMove
With ContextMenuStrip1
Try
Dim sItemText As String = .GetItemAt(PointToScreen(MousePosition)).Text
Label1.Text = sItemText
Catch ex As Exception
Label1.Text = ex.Message
End Try
End With
End Sub
Private Sub ContextMenuStrip1_Opening(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles ContextMenuStrip1.Opening
tmrCM.Start()
End Sub
End Class It's Not bad? for a start.up, hope it helps.:)
Hey,
I happened to be working on this problem myself right now. Here is a simple bit of code you can add to the TextChanged event to give the Append autocomplete function anywhere in the textbox. It uses the AutoCompleteUstomSource already loaded for the TextBox
Private Sub TextBox1_TextChanged(sender As System.Object, e As System.EventArgs) Handles TextBox1.TextChanged
'Requires class level variable in order to stop event self-referencing
If ImAdding Then Exit Sub
'Load textbox.AutoCustomCompleteSource into List (of String)
Dim SourceList As New List(Of String)
For Each s As String In TextBox1.AutoCompleteCustomSource
SourceList.Add(s)
Next
'Get last word entered
Dim Txt = Trim(CStr(TextBox1.Text))
Dim lastIndex As Integer = IIf(Txt.LastIndexOf(" ") = -1, 0, Txt.LastIndexOf(" ") + 1)
Dim CursorPosition As Integer = TextBox1.SelectionStart
Dim lastWord As String = Trim(Txt.Substring(lastIndex))
'Get word suggestions
Dim Suggestions As IEnumerable(Of String)
If Txt <> "" Then
Suggestions = From c In SourceList Where c.StartsWith(lastWord, StringComparison.CurrentCultureIgnoreCase) Select c
End If
'Add word completion if available
Try
If Suggestions(0) <> "" Then
ImAdding = True
Dim addition As String = Suggestions(0)
lastIndex = addition.IndexOf(lastWord, 0, Len(addition), StringComparison.CurrentCultureIgnoreCase) + Len(lastWord)
Dim endofWord As String = Trim(addition.Substring(lastIndex))
TextBox1.Text &= endofWord
TextBox1.SelectionStart = CursorPosition
TextBox1.SelectionLength = TextBox1.Text.Count
ImAdding = False
End If
Catch ex As Exception
End Try
End Sub
This should go well with the dropdown being developed.
Hey,
I added the code to give a dropdown list as suggested above. Key handlers have also been added to automatically accept appended data when the space or enter keys are pressed, similar to how Intellisense works. Typed values are replaced with those from custom complete list in order to preserve preferred capitalization. The code is also generic so that any TextBox that uses the tb_TextChanged and tb_KeyDown methods will have the same dropdown capabilities. When the list of suggestions is less than 5, the search method switches from "StartsWith" to "Contains" to find all possible matches to the entered text.
Code contains 6 Class variables and 3 Methods for TextChanged and KeyDown Events, and for the "DropDown" click.
This will be useful when entering lists such as e-mail adressess or formulas.
Private ImAdding As Boolean = False
Private ImDone As Boolean = False
Private IveBeenClicked As Boolean = False
Private tb As New TextBox
Private newWord As String
Private cmsDropDown As New ContextMenuStrip
Private Sub tb_TextChanged(sender As System.Object, e As System.EventArgs) Handles TextBox1.TextChanged
'Exit conditions: ImAdding prevents recursive event call, ImDeleting allows Backspace to work
If bLoading Or ImAdding Or ImDone Or IveBeenClicked Or Trim(sender.text) = "" Then
cmsDropDown.Close()
Return
End If
'Close old dropdown lists
cmsDropDown.Close()
'Get last word entered
tb = sender
Dim CursorPosition As Integer = tb.SelectionStart
Dim Txt = Trim(CStr(tb.Text))
Dim lastIndex As Integer = IIf(Txt.LastIndexOf(" ") = -1, 0, Txt.LastIndexOf(" ") + 1)
Dim lastWord As String = Trim(Txt.Substring(lastIndex))
'Get word suggestions based on word start for Append function
Dim StringList As New List(Of String)
For Each c In tb.AutoCompleteCustomSource
StringList.Add(c)
Next
Dim Suggestions As IEnumerable(Of String) = From c In StringList Where c.StartsWith(lastWord, StringComparison.CurrentCultureIgnoreCase) Select c
'Append word if available
If Not (Suggestions(0) Is Nothing) Then
ImAdding = True
newWord = Suggestions(0)
lastIndex = newWord.IndexOf(lastWord, 0, Len(newWord), StringComparison.CurrentCultureIgnoreCase) + Len(lastWord)
Dim endofWord As String = Trim(newWord.Substring(lastIndex))
tb.Text &= endofWord
tb.SelectionStart = CursorPosition
tb.SelectionLength = tb.Text.Count
ImAdding = False
End If
'Reset suggestion list to 'contains' if list is small - NOW CASE SENSITIVE
If Suggestions.Count < 5 Then
Suggestions = From c In StringList Where c.IndexOf(lastWord, StringComparison.InvariantCultureIgnoreCase) <> -1 Select c 'c.Contains(lastWord)
End If
'Display dropdown list
If Suggestions.Count > 1 Then
With cmsDropDown
.Items.Clear()
For iCount As Integer = 0 To IIf(Suggestions.Count > 25, 25, Suggestions.Count)
.Items.Add(Suggestions(iCount))
AddHandler .Items(iCount).Click, AddressOf cmsDropDown_Click
Next
.AutoSize = False
.AutoClose = False
.Width = tb.Width
.Font = tb.Font
.BackColor = tb.BackColor
.MaximumSize = New Size(tb.Width, 200)
.LayoutStyle = ToolStripLayoutStyle.VerticalStackWithOverflow
.Show(tlpBasic, tb.Location.X, tb.Location.Y + tb.Height)
End With
'set focus back to original control
tb.Focus()
Else
cmsDropDown.Close()
End If
End Sub
Private Sub cmsDropDown_Click(sender As System.Object, e As System.EventArgs)
cmsDropDown.Close()
'Get last word of TextBox
Dim Txt = Trim(CStr(tb.Text))
Dim lastIndex As Integer = IIf(Txt.LastIndexOf(" ") = -1, 0, Txt.LastIndexOf(" ") + 1)
'Set to new value
With tb
.SelectionStart = lastIndex
.SelectionLength = .TextLength
.SelectedText = sender.text
End With
IveBeenClicked = True
End Sub
Private Sub tb_KeyDown(sender As System.Object, e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyDown
Select Case e.KeyCode
Case Keys.Back
ImDone = True
IveBeenClicked = False
newWord = ""
Case Keys.Space
'If tb.SelectionLength = 0 Then
Dim Txt = Trim(CStr(tb.Text))
Dim lastIndex As Integer = IIf(Txt.LastIndexOf(" ") = -1, 0, Txt.LastIndexOf(" ") + 1)
'Set to new value
If newWord <> "" Then
With tb
.SelectionStart = lastIndex
.SelectionLength = .TextLength
.SelectedText = newWord
End With
newWord = ""
End If
'End If
tb.SelectionStart = tb.TextLength
ImDone = True
IveBeenClicked = False
Case Keys.Enter
Dim Txt = Trim(CStr(tb.Text))
Dim lastIndex As Integer = IIf(Txt.LastIndexOf(" ") = -1, 0, Txt.LastIndexOf(" ") + 1)
'Set to new value
If newWord <> "" Then
With tb
.SelectionStart = lastIndex
.SelectionLength = .TextLength
.SelectedText = newWord
End With
newWord = ""
End If
tb.SelectionStart = tb.TextLength
ImDone = True
IveBeenClicked = False
newWord = ""
Case Else
ImDone = False
IveBeenClicked = False
End Select
End Sub
Hope this solves your problem.
Hi guys, i am sorry for the late response, was on vacation. Now to the fun again lol. I will try the 3 solutions and will let know the results. Thank you for all your help.
Eagerly, Not waiting.:D
btw, hope you enjoyed your vacation and that you were only thinking about the pussy.cat and vb.net.