I'm Trying autocomplete with textbox event TextChanged but running a bit delay/slow when type,reduce character (press backspace) and Choose from AutoComplete in VB.NET.
even though there are only 9 records sample because if I use it with hundreds of actual records then it will obviously make it slow
I use the code below the solution is fast but the results in textbox2 don't appear I don't know if there is something wrong with my code
Please provide a solution according to the code below :
Thanks
Imports System.ComponentModel
Imports System.Data.OleDb
Imports Dapper
Public Class Form3
Private iService As New ItemService()
Private bindingSource1 As BindingSource = Nothing
Private Sub Form3_Load(sender As Object, e As EventArgs) Handles MyBase.Load
lblcodeproduct.Visible = False
TextBox1.AutoCompleteMode = AutoCompleteMode.Suggest
TextBox1.AutoCompleteSource = AutoCompleteSource.CustomSource
TextBox1.AutoCompleteCustomSource.AddRange(iService.GetByCodeProduct().Select(Function(n) n.CodeProduct).ToArray())
End Sub
Private Sub GetItemData2(ByVal iditem As String)
Dim item = iService.GetByCodeProductOrBarcode(iditem)
If item IsNot Nothing Then
If String.Equals(iditem, item.CodeProduct, StringComparison.CurrentCultureIgnoreCase) Then
TextBox1.Text = item.CodeProduct
End If
TextBox2.Text = item.Barcode
Else
TextBox2.Clear()
Return
End If
End Sub
Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
If _typingTimer Is Nothing Then
' WinForms:
_typingTimer = New Timer()
_typingTimer.Interval = 300
Static recursive As Boolean = False '<<<<<<<<<<<<<<<<<<<<<<<<<
If recursive Then Exit Sub '<<<<<<<<<<<<<<<<<<<<<<<<<
recursive = True '<<<<<<<<<<<<<<<<<<<<<<<<<
If TextBox1.Text = "" Then
TextBox2.Clear()
lblcodeproduct.Visible = False
ErrorProvider1.SetError(TextBox1, "")
recursive = False '<<<<<<<<<<<<<<<<<<<<<<<<<
Else
Try '<<<<<<<<<<<<<<<<<<<<<<<<<
bindingSource1 = New BindingSource With {.DataSource = New BindingList(Of Stock)(CType(iService.GetByCodeProductlike(TextBox1.Text), IList(Of Stock)))}
If bindingSource1.Count > 0 Then
lblcodeproduct.Visible = False
ErrorProvider1.SetError(TextBox1, "")
Else
lblcodeproduct.Visible = True
End If
' the following method might change TextBox1
' which results in the .TextChanged event being called again
' the changes mean that second call stops the processing of the .TextChanged event
GetItemData2(TextBox1.Text)
Finally '<<<<<<<<<<<<<<<<<<<<<<<<<
recursive = False '<<<<<<<<<<<<<<<<<<<<<<<<<
End Try
End If
AddHandler _typingTimer.Tick, AddressOf handleTypingTimerTimeout
_typingTimer.Stop() ' Resets the timer
_typingTimer.Tag = (TryCast(sender, TextBox)).Text ' This should be done with EventArgs
_typingTimer.Start()
End Sub
Private Sub handleTypingTimerTimeout(ByVal sender As Object, ByVal e As EventArgs)
Dim timer As Timer = TryCast(sender, Timer) ' WinForms
If timer Is Nothing Then
Return
End If
' The timer must be stopped! We want to act only once per keystroke.
timer.Stop()
End Sub
End Class
Public Class Stock
Public Property Id() As Integer
Public Property CodeProduct() As String
Public Property Barcode() As String
End Class
Public Class ItemService
Public Function GetOledbConnectionString() As String
Return "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\TRIAL.accdb;Persist Security Info=False;"
End Function
Private ReadOnly _conn As OleDbConnection
Private _connectionString As String = GetOledbConnectionString()
Public Sub New()
_conn = New OleDbConnection(_connectionString)
End Sub
Public Function GetByCodeProduct() As IEnumerable(Of Stock)
Dim sql = "SELECT CodeProduct AS CodeProduct FROM Items"
Using _conn = New OleDbConnection(GetOledbConnectionString())
Return _conn.Query(Of Stock)(sql).ToList()
End Using
End Function
Public Function GetByCodeProductlike(ByVal CodeProduct As String) As IEnumerable(Of Stock)
Dim sql = $"SELECT CodeProduct FROM Items WHERE CodeProduct LIKE '%" & CodeProduct & "%'"
Using _conn = New OleDbConnection(GetOledbConnectionString())
Return _conn.Query(Of Stock)(sql).ToList()
End Using
End Function
Public Function GetByCodeProductOrBarcode(ByVal code As String) As Stock
Dim sql = $"SELECT * FROM Items WHERE CodeProduct = '{code}' or Barcode = '{code}'"
Using _conn = New OleDbConnection(GetOledbConnectionString())
Return _conn.Query(Of Stock)(sql).FirstOrDefault()
End Using
End Function
End Class
Below Google Drive link GIF file
RESULT UPDATE CODE
Below Google Drive link Database
sample database