Criando um ComboBox com pesquisa incremental

 

Uma preocupação comum dos desenvolvedores atuais é com a funcionalidade e facilidade de suas aplicações. Logicamente, nesse cenário entra a enorme produtividade da ferramenta Microsoft Visual Studio 2005. Mas mesmo com todos os recursos oferecidos, às vezes nos deparamos com situações onde necessitamos de algo mais que o padrão.

Exemplo disso, é colocar um simples ComboBox na sua aplicação para facilitar algum tipo de pesquisa. Aqui começa o problema, pois esse componente não possui uma pesquisa incremental, o que o torna um tanto complicado de se utilizar, pois imagine o usuário ter que pesquisar uma enorme lista de clientes, usando apenas a primeira letra do nome e depois clicando com o mouse até encontrar o que precisa.

Felizmente os componentes do .NET Framework podem ser estendidos, ou seja, podemos acrescentar funcionalidades de acordo com as nossas necessidades. Esse é o princípio da herança, um dos pilares da programação Orientada a Objetos, e é através desse recurso que vamos criar nosso componente de pesquisa incremental.

Usando a herança para criar o novo componente

O que queremos, é criar um ComboBox que permita realizar uma pesquisa incremental, ou seja, ir posicionando a informação à medida que vamos digitando.

Como todo o .NET Framework foi construído baseado nos padrões de Orientação a Objetos, criaremos um novo controle baseado no existente, que está localizado no namespace System.Windows.Forms.ComboBox. Esse novo controle possuirá as mesmas características do controle original.

Para nosso exemplo, iremos criar um projeto Windows Forms no Visual Studio .Net (File / New Project / Visual C#  / Windows Forms) , isto pode ser feito como demonstrado na Figura 1.

 

 

Figura 1. Criando o projeto no Visual Studio 2005

Agora vamos adicionar uma nova classe ao projeto, onde iremos construir nosso componente. Veja Primeiramente click com o botão direito do mouse em cima do nome do projeto no Solution Explorer, depois clique em Add / New / Class e dê o nome de CDSComboBox, você verá a janela mostrada na Figura 2.

 

 

Figura 2. Adicionando uma nova classe ao projeto

Agora que já criamos a classe, vamos colocar a funcionalidade de pesquisa incremental. Isso é feito através de uma variável interna da classe que guardará todas as teclas que serão digitadas e capturadas pelo método ProcessCmdKey. Veja o respectivo código na Listagem 1.

 

Listagem 1. Colocando a variável interna que guardará as teclas digitadas

using System;

using System.Collections;

using System.ComponentModel;

using System.Drawing;

using System.Data;

using System.Windows.Forms;

 

namespace CDSSoftware

{

   public class CDSComboBox: System.Windows.Forms.ComboBox

   {

       // variável para string de pesquisa

       private string strPesq = "";

      

       public CDSComboBox()

       {

          // muda o estilo do ComboBox para

          //DropDownList

          this.DropDownStyle = ComboBoxStyle.DropDownList;

       }

   }

}

No construtor da classe CDSComboBox, configuramos a propriedade DropDownStyle para DropDownList, pois essa aparência garante uma funcionalidade melhor ao componente. Mas não é necessário mantê-la e isso dependerá de você.  O método ProcessCmdKey é o responsável por processar todas as teclas e comandos enviados ao ComboBox. Iremos reescrevê-lo, acrescentando as novas funcionalidades. O novo método pode ser visto na Listagem 2.

 

Listagem 2. Método ProcessCmdKey captura as teclas digitadas

// sobreposição do método que processa as teclas

protected override bool ProcessCmdKey(

  ref Message msg, Keys keyData)

{

       bool bProc = true;

       int i;

        if (keyData == Keys.Back)

        {

           if (strPesq.Length > 0)

           {

               strPesq = strPesq.Substring(0,

                 strPesq.Length - 1);

           }

        }

        if(keyData != Keys.Up && keyData != Keys.Down &&

          keyData != Keys.Return && keyData != Keys.Tab)

        {

            if(keyData == Keys.Space)

            {

             strPesq += " ";

            }

            else

            {

               if (keyData != Keys.Back)

               {

                  strPesq += keyData.ToString();

               }

            }

                   

            i = this.FindString(strPesq);

            if(i > -1)

            {

             this.SelectedIndex = i;

            }

            bProc = false;

        }

        else

        {

            if(keyData == Keys.Up || keyData == Keys.Down)

            {

                strPesq = "";

            }

        }

        if(keyData == Keys.Return)

        {

            SendKeys.Send("{Tab}");

        }

        if(!bProc)

        {

            return true;

        }

        else

        {

            return base.ProcessCmdKey (ref msg, keyData);

        }

}

Entendendo o método ProcessCmdKey

Esse método capturará todas as teclas digitadas e armazená-las na variável strPesq ,que é usada no método FindString para realizar a pesquisa efetivamente. Esse método retorna o número da linha que possui a string correspondente ou -1 caso não encontre nada. Utilizamos então o número da linha para posicionar o ComboBox através da propriedade SelectedIndex.

Existem algumas teclas que precisamos dar um tratamento especial dentro do componente. Essas teclas são:

·         BackSpace: apaga o último caractere digitado;

·         Setas de direção (para Cima, para Baixo): limpam a pesquisa;

·         Espaço: inclui o caractere espaço;

·         Enter: simulamos o pressionamento da tecla TAB, através da função SendKeys.Send.

 

Por último, mantemos uma variável de controle (bProc), que indica quando a pesquisa é realizada, pois caso nenhuma tecla tenha sido tratada, devemos chamar a função original base.ProcessCmdKey. Lembrando que como estamos reescrevendo um método que já existe no componente original, precisamos chamar o método original, a fim de manter as funcionalidades básicas do mesmo.

Utilizando o Componente

Para utilizar a nova classe basta adicionar o arquivo com o código fonte do componente ao seu projeto e arrastá-lo para um formulário. Após a primeira compilação (Build / Build Solution), este componente aparecerá na Toolbox, de acordo com a Figura 3.

 

        

Figura 3. Componente CDSComboBox aparecendo na Toolbox

O componente irá se comportar exatamente igual ao ComboBox original, mas com a pesquisa incremental. Para configurá-lo, utilize a janela Properties do Visual Studio, ligando ao controle DataSet da sua aplicação.  

Considerações sobre a Combobox do Visual Studio 2005

Na versão 2005 do Visual Studio, a pesquisa incremental foi adicionada ao componente padrão, e pode ser configurada mudando-se as seguintes propriedades:

Configurando-se a propriedades:

·         AutoCompleteMode = Append

·         AutoCompleteSourec = ListItens

·         DropDownStyle = DropDownList

Conclusões

Demonstramos aqui como é possível estender as funcionalidades do .NET Framework, através do mecanismo de herança e o quanto é simples melhorar as funcionalidades dos componentes existentes. Como uma dica, você pode criar a mesma funcionalidade para o ComboBox presente no DataGridView. Mas isso fica como um desafio para vocês. Um grande abraço e até a próxima!!!

 

Carlos dos Santos (cdssoftware@hotmail.com) é desenvolvedor certificado Microsoft em C#. É também líder do Grupo de Usuários de Cornélio Procópio/PR (Gup .Net), e faz palestras em diversos locais sobre a tecnologia Microsoft .Net. Trabalha com desenvolvimento de aplicações Windows, Web e para dispositivos móveis. com as linguagens Delphi, C e C# há vários anos.