Normalmente sou desconfiado de soluções de auto-complete. Vou realizar um próximo post, que mostra como fazer a mesma coisa utilizando JQuery. Porém a solução do Jquery exige que você coloque todas as informações da consulta no formato Json no momento em que carrega a página, isso pode ser eficiente para poucos registros, para grande quantidades de registros, acredito que o Auto Complete do Ajax Control Toolkit seja mais indicado.
Imagem 1 | Vou utilizar Linq To Sql para a implementação deste exemplo, pois acredito que é um dos frameworks que trazem maior produtividade em desenvolvimento. Estou utilizando dados e exemplos de um projeto real que está em produção, por isso, os nomes não sejam conhecidos como o Northwind ou Pubs. Bom, vamos primeiro entender a estrutura. Criei uma entidade (utilizando o LinToSql). (Imagem 1), assim, teremos acesso aos dados e podemos criar os métodos para acessos aos dados utilizando o mapeamento relacional gerado automaticamente. |
Vamos agora criar o método que será utilizado pelo webservice que é necessário para utilização do auto-complete.
using System;
using System.Linq;
namespace PitStop.Dados
{
public class CadastroCliente : IDisposable
{
//Crio a variavel que irá conter o contexto dos Dados.
private dbDataContext dbContext;
/// <summary>
/// Construtor da classe.
/// </summary>
public CadastroCliente()
{
//No construtor, crio a instancia do contexto.
dbContext = new dbDataContext();
}
/// <summary>
/// Retorna clientes que possam atender a consulta
/// </summary>
/// <param name="textoBuscar">Parte do nome do cliente</param>
/// <param name="count">Quantidade de itens que serão retornados</param>
/// <returns>array com nome dos clientes</returns>
public string[] RetornarNomesClientes(string textoBuscar, int count)
{
//Aqui é um pulo do gato, como vamos apenas fazer a consulta, desabilitamos o tracking que por padrão fica habilitado.
//Funciona apenas para consulta, qualquer ação que necessite que o estado seja salvo (Update, Insert, Delete) é necessário habilitar.
dbContext.ObjectTrackingEnabled = false;
return dbContext.ClienteEntidades
.Where(p => p.Inativo == false && p.Nome.ToLower().Contains(textoBuscar)) // Filtro clientes ativos e que contenham o texto.
.Select(m => m.Nome) // não há necessidade da entidade inteira, então, retorno apenas o nome
.Take(count) // retorno apenas a quantidade quantidade necessária
.ToArray(); // Converto o resultado para um array.
}
// Fecho o que pode estar aberto.
#region IDisposable Members
~CadastroCliente()
{
this.Dispose();
}
public void Dispose()
{
GC.Collect();
GC.SuppressFinalize(this);
}
#endregion
}
}
Agora, vamos criar o WebService que será chamado pelo componente do AutoCompleteExtender. Clique com o Botão direito e selecione o item “WebService”.
Ao adicionar o WebService, vamos criar o método responsável por invocar o método que criamos nos passos anteriores.
using System.Web.Services;
using PitStop.Dados;
namespace PitStop.Web.webService
{
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
[System.Web.Script.Services.ScriptService]
public class AutoComplete : System.Web.Services.WebService
{
public AutoComplete()
{
}
/// <summary>
/// Retorna dados para o autoComplete
/// </summary>
/// <param name="prefixtext">Texto que será pesquisado</param>
/// <param name="count">Quantidade de registros que serão retornados</param>
/// <returns>array com nome dos clientes</returns>
[WebMethod]
public string[]RetornarClientes(string prefixtext, int count)
{
using (CadastroCliente cad = new CadastroCliente())
{
return cad.RetornarNomesClientes(prefixtext, count);
}
}
}
}
Pronto, estrutura pronta agora vamos preparar a interface, que consumirá a informação
Em uma nova página aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="TesteComplete.aspx.cs" Inherits="PitStop.Web.TesteComplete" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Teste Auto Complete</title>
<style type="text/css">
.autocomplete_list {visibility:visible;margin:0px!important;padding:1px;background-color:GrayText;color:Black;
border:buttonshadow;border-width:1px;border-style:solid;cursor:default;text-align:left;list-style-type:none;
font-weight:normal;font-family:Verdana;font-size:10px;}
.autocomplete_highlighted_listitem {background-color: GrayText;color:Black;padding:3px;}
.autocomplete_listitem {background-color:Window;color:Gray;font-family: Verdana;font-size: 10px;padding:3px;}
</style>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ToolkitScriptManager ID="sm" runat="server" />
<asp:AutoCompleteExtender ID="ace" runat="server"
EnableCaching="true"
MinimumPrefixLength="1"
TargetControlID="txtNome"
ServicePath="~/webService/AutoComplete.asmx"
ServiceMethod="RetornarClientes"
CompletionInterval="10"
CompletionSetCount="10"
CompletionListCssClass="autocomplete_list"
CompletionListItemCssClass="autocomplete_listitem"
CompletionListHighlightedItemCssClass="autocomplete_highlighted_listitem">
</asp:AutoCompleteExtender>
<asp:TextBox ID="txtNome" runat="server" CssClass="campoForm" Width="400px" autocomplete="off" />
</div>
</form>
</body>
</html>
Vale algumas dicas:
CompletionSetCount = 10 –> Indica a quantidade de registros que serão exibidos na lista do auto-complete.
EnableCaching = true –> Guarda as ultimas consultas realizadas.
MinimumPrefixLength = 1 –> Indica a partir de quantos caracteres digitados será realizado o auto-complete (o ideal seria 3 a 5)
CompletionListCssClass, CompletionListItemCssClass e CompletionListHighlightedItemCssClass você consegue alterar o estilo (css) do auto-complete.
Uma coisa legal é autocomplete="off" que utilizei no TextBox (txtNome) isso indica que não será utilizado o autocomplete do browser, pois, isso pode confundir o usuário.
Vamos ver o resultado?

Espero que tenham gostado... Dúvidas ou sugestões de artigos entrem em contato ;-).
Até a próxima.
35594e56-a268-4546-b371-2e1e8ee6eab2|2|5.0