WPF - Simulando o recurso AutoCompletar e usando o controle AutoCompleteBox


Neste artigo vou mostrar como simular o recurso AutoCompletar em uma aplicação WPF e também como usar o controle AutoCompleteBox da WPF ToolKit.

Vamos iniciar simulando o recurso auto-completar usando um controle TextBox e um controle ListBox, de forma que ao digitar cada caractere no controle TextBox os valores serão obtidos da fonte de dados, filtrados e exibidos no controle ListBox. Selecionando um item do ListBox o mesmo será exibido no controle DataGrid.

Vamos usar como fonte de dados o banco de dados Northwind.mdf e a tabela Customers de forma a exibir o nome do contato (ContactName).

Inicie o Visual Basic 2010 Express Edition e no menu File -> New Poject selecione o template WPF Application e informe o nome Wpf_AutoComplete;

A seguir no arquivo MainWindow.xaml vamos incluir 1 controle TextBox , 1 controle ListBox e 1 controle DataGrid conforme o leiaute abaixo:

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="WPF - AutoCompletar" Height="253" Width="467">
    <Grid Height="191" Width="421" Background="White">
        <TextBox Height="23" HorizontalAlignment="Left" Margin="36,23,0,0" Name="txtAutoCompletar" VerticalAlignment="Top" Width="120" />
        <ListBox Height="100" HorizontalAlignment="Left" Margin="35,48,0,0" Name="lstAutoCompletar" VerticalAlignment="Top" Width="120" 
BorderBrush="White" />
        <DataGrid AutoGenerateColumns="True" Height="147" HorizontalAlignment="Left" Margin="190,23,0,0" Name="MacorattiGrid" 
VerticalAlignment="Top" Width="200"  SelectionMode="Single" BorderBrush="#FF00DAF8" />
    </Grid>
</Window>

O controle DataGrid tem a sua propriedade SelectionMode configurada para Single, e, o controle ListBox tem sua propriedade BorderBrush definida como White.

Vamos criar o data source usando o banco de dados Northwind.mdf.

Vamos agora definir o código no arquivo MainWindow.xaml.vb referente aos eventos TextChanged do controle TextBox e SelectionChanged do controle ListBox.

Abra o arquivo MaindWindow.xaml.vb e defina os namespaces que iremos usar:

Imports System.Data
Imports System.Data.SqlClient

A seguir vamos definir a string de conexão (podemos obtê-la do arquivo App.Config também) conforme a seguir:

Dim conn As New SqlConnection("Data Source=.\SQLEXPRESS;AttachDbFilename=C:\NORTHWND.MDF;Integrated Security=True;Connect Timeout=30;User Instance=True")
Dim dr As SqlDataReader

A seguir no evento TextChanged do controle TextBox vamos incluir o código a seguir:

Private Sub txtAutoCompletar_TextChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.TextChangedEventArgs) Handles txtAutoCompletar.TextChanged
        lstAutoCompletar.Items.Clear()
        Try
            conn.Open()
            Dim comm As New SqlCommand("SELECT ContactName FROM Customers WHERE ContactName like '" + txtAutoCompletar.Text + "%'", conn)
            dr = comm.ExecuteReader()
            While dr.Read()
                lstAutoCompletar.Items.Add(dr.GetValue(0).ToString())
            End While
        Catch ex As Exception
            MessageBox.Show(ex.Message.ToString())
        Finally
            conn.Close()
        End Try

    End Sub

Neste código abrimos uma conexão com o banco de dados e executamos a seguinte instrução SQL :

SELECT ContactName FROM Customers WHERE ContactName like '" + txtAutoCompletar.Text + "%'"

Essa instrução utiliza a palavra reservada Like e também o caractere % que permite realizar um filtro a cada caractere digitado na caixa de texto visto que o código será executado sempre que algo mudar no controle TextBox.

Os resultados são exibidos no controle ListBox através do datareader:

While dr.Read()
     lstAutoCompletar.Items.Add(dr.GetValue(0).ToString())
End While

No evento SelectionChange do controle ListBox temos o seguinte código:

Private Sub lstAutoCompletar_SelectionChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs) Handles lstAutoCompletar.SelectionChanged
        Try
            conn.Open()
            Dim comm As New SqlCommand("SELECT ContactName FROM Customers Where ContactName='" + lstAutoCompletar.SelectedItem.ToString() + "'", conn)
            Dim ds As New DataSet()
            Dim da As New SqlDataAdapter(comm)
            da.Fill(ds)
            MacorattiGrid.ItemsSource = ds.Tables(0).DefaultView
        Catch ex As Exception
            MessageBox.Show(ex.Message.ToString())
        Finally
            conn.Close()
        End Try
    End Sub

Este código obtém o valor do item selecionado no ListBox e o exibe no controle DataGrid.

Executando o projeto e digitando os caracteres Jo na caixa de texto, após selecionar o item Jonas Bergulfsen iremos obter o resultado a seguir:

Dessa forma estamos simulando o recurso AutoCompletar usando um TextBox e um Listbox.

Mas existe uma maneira mais fácil de fazer isso usando o controle AutoCompleteBox da WPF ToolKit.

Usando o controle AutoCompleteBox

Para poder usar o controle AutoCompleteBox devemos referenciar a WPF ToolKit em nosso projeto.

Se você ainda não tem a WPF ToolKit instalada faça o download aqui: http://wpf.codeplex.com/releases/view/40535

Após isso inicie o Visual Basic 2010 Express Edition e no menu File -> New Poject selecione o template WPF Application e informe o nome Wpf_AutoCompleteBox;

Em seguida vamos referenciar a WPF ToolKit no nosso projeto.

No menu Project selecione Add Reference e a seguir localize o arquivo WPFToolKit.dll selecionando e clicando em OK;

Obs:O namespace System.Windows.Controls.Input usa a WPFToolkit.dll.

A seguir defina o seguinte leiaute no arquivo MainWindow.xaml :

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       xmlns:Controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit"
    Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.Background>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="Black" Offset="0" />
                <GradientStop Color="#00FFFF00" Offset="1" />
            </LinearGradientBrush>
        </Grid.Background>
        <Controls:AutoCompleteBox x:Name="macComplete" VerticalAlignment="Top" Margin="78,21,37,0" Height="39" />
    </Grid>
</Window>

Para encerrar vamos definir no evento Loaded da janela MainWindow o seguinte código:

Imports System.Collections.Generic
Imports System.Windows

Class MainWindow

    Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) 
Handles MyBase.Loaded

        Dim listaNomes As New List(Of String)() From {"Albert Fernando", _
                                                                             "Antonio Banderas", _
                                                                             "Alexandre Pires", _
                                                                             "Barbara Moore", _
                                                                             "Brad Pit", _
                                                                             "Bob Dylan", _
                                                                             "Cameron Diaz", _
                                                                             "Catherina Biel", _
                                                                             "Christopher Ben", _
                                                                             "Jose Carlos Macoratti", _
                                                                             "Janice Rachel", _
                                                                             "Jefferson Andre", _
                                                                             "Jessica Naara", _
                                                                             "Miriam Estela", _
                                                                             "Mario Fernandes" _
                                                                             }
        macComplete.ItemsSource = listaNomes
    End Sub
End Class

Neste código definimos uma coleção de nomes de artistas (conhece todos ???) e em seguida atribuímos a lista a propriedade ItemsSource do controle AutoCompleteBox.

Executando o projeto iremos e digitando um caractere J iremos obter:

Usar o controle AutoCompleBox é muito mais simples não é mesmo ???

Pegue os dois projetos completos aqui: Wpf_AutoCompletar e Wpf_AutoCompleteBox

Eu sei é apenas WPF, mas eu gosto...

"Passará o céu e a terra, mas as minhas palavras jamais passarão." (Mateus 24:35)

Referências:

José Carlos Macoratti