VB.NET - Busca Dinâmica em um ComboBox
Preencher uma comboBox e efetuar uma busca dinâmica nos itens adicionados a mesma é uma tarefa corriqueira no dia a dia de um programador. Neste artigo vou mostrar como você pode preencher um comboBox com os dados de uma tabela e a seguir permitir uma busca dinâmica nos itens inseridos quando o usuário digitar na caixa de texto da combo.
Eu já mostrei uma forma de fazer a mesma coisa no artigo : VB .NET - Criando uma Combobox com recurso Auto Completar. Neste artigo além da mostrar outra maneira de obter o mesmo resultado estou usando o acesso a um banco de dados Access - Northwind.mdb - e selecionando os dados da tabela produtos para exibir o nome do produto na combobox.
- Inicie um novo projeto no Visual Studio.NET com as seguintes características (sinta-se a vontade para alterar a seu gosto.)
No formulário padrão form1.vb insira um controle combobox e um controle Button conforme a figura abaixo:
No evento Load do formulário eu vou inserir o código que acesso o banco de dados , seleciona os dados da tabela e preenche a combobox. (Não é a maneira mais elegante de fazer este serviço , você poderia criar uma classe e remover o código do formulário)
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load 'Retorna os nomes dos produtos da tabela produtos Dim strConn As String = "Provider=Microsoft.JET.OLEDB.4.0;Data Source = c:\teste\Northwind.mdb" Dim dbConn As System.Data.OleDb.OleDbConnection = New System.Data.OleDb.OleDbConnection(strConn) dbConn.Open() Dim DSet As New DataSet(), SQLStr As String Dim cmd As System.Data.OleDb.OleDbCommand Dim dbAdaptr As System.Data.OleDb.OleDbDataAdapter = New System.Data.OleDb.OleDbDataAdapter() 'cria o objeto datarow e datatable Dim tRow As DataRow, tTbl As DataTable 'mapeia a tabela produtos , monta o sql para selecionar os nomes dos produtos 'e executa o objeto command preenchendo a seguir o dataset With dbAdaptr .TableMappings.Add("Table", "Produtos") SQLStr = "Select [NomeDoProduto] from Produtos order by NomeDoProduto" cmd = New System.Data.OleDb.OleDbCommand(SQLStr, dbConn) cmd.CommandType = CommandType.Text .SelectCommand = cmd .Fill(DSet) .Dispose() End With DSet.AcceptChanges() tTbl = DSet.Tables.Item(0) DSet.Dispose() dbConn.Close() ' preenche o combo combobox cboAuto.Text = "" cboAuto.Items.Clear() cboAuto.BeginUpdate() ' carrega o combo com o nome dos produtos For Each tRow In tTbl.Rows cboAuto.Items.Add(tRow("NomeDoProduto").ToString) Next cboAuto.EndUpdate() End Sub
|
A seguir vou comentar as partes que acho interessante no código acima.
- .TableMappings.Add("Table", "Produtos") - Quando um data adapter lê os dados de uma fonte de dados ele determina onde por os dados na tabela correspondente usando o mapeamento para a tabela. O mapeamento vincula o nome das colunas no fonte com aqueles da tabela no DataSet.
- .SelectCommand = cmd - Obtêm ou define um comando SQL ou procedimento armazenado usado para selecionar os registros na fonte de dados. Se a propriedade não retornar nenhuma linha de registro , não haverá tabela incluída no DataSet.
-DSet.AcceptChanges() - Atualiza todas as alterações feitas para o DataSet desde que ele foi carregado ou até a última vez que o método foi chamado. Tanto a classe DataTable como DataRow possui o método AcceptChanges ;Ao invocar o método em um DataSet faz com que ele seja chamado em cada tabela do DataSet. Desta maneira você tem múltiplos níveis no qual o método pode ser chamado.
- cboAuto.BeginUpdate()/ cboAuto.EndUpdate() - O método BeginUpdate evita que o controle seja redesenhado até que o método EndUpdate e assim mantêm o desempenho quando itens são incluídos na combobox. A melhor forma de preencher uma combobox é usar o método AddRange da classe ComboBox.Collection pois isto permite que você inclua um array de itens na lista de uma vez. Se você quer incluir item a item ( que é o nosso caso) pode usar o método Add e pode usar então o método BeginUpdate para evitar que o controle seja redesenhado a cada item incluído na lista. Após terminar a tarefa chame o método EndUpdate para que o controle seja redesenhado. Isto pode previnir que a tela sofra o efeito de tremulação durante o desenho do controle se a quantidade de itens for muito grande.
No evento Change do comboBox incluimos o código que realiza a busca:
' Usamos o evento "Change" para uma busca alfabetica Private Sub cboAuto_TextChanged(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles cboAuto.TextChanged Dim boxIndex As Integer, lExst As Boolean Dim box As ComboBox = sender Dim txt As String = box.Text Dim posCursor As Integer = box.SelectionStart ' Se o cursor não estiver no inicio do textbox inicia a busca If posCursor <> 0 Then lExst = False ' Procura na combo pela entrada na lista For boxIndex = 0 To box.Items.Count - 1 If UCase(Mid(box.Items(boxIndex), 1, posCursor)) = UCase(Mid(txt, 1, posCursor)) Then box.Text = box.Items(boxIndex) box.SelectionStart = posCursor lExst = True Exit For End If Next ' Se não encontrar retorna o valor anterior If Not lExst Then box.Text = Mid(txt, 1, posCursor - 1) + Mid(txt, posCursor + 1) box.SelectionStart = posCursor - 1 End If End If End Sub
|
Executando o projeto teremos:
Até o próximo artigo...
José Carlos Macoratti