domingo, 14 de julio de 2013

AutoComplete TextBox usando Listas Genericas

En muchas ocasiones se nos solicita el Plus de implementar la función AutoComplete en un control TextBox para aplicar un filtro a una Bd conforme el usuario vaya tecleando sobre el control o simplemente a nosotros se nos ocurre simular el Autocomplete de Google dando con esto una mejor experiencia de usuario.
Les dejo este pequeño ejemplo en donde usando una Lista Genérica de propiedades se logra cargar el objeto AutoCompleteStringCollection propio de los controles que cuentan con la característica del AutoComplete, evitando con esto que por cada tecla ingresada en el control TextBox se tenga que lanzar una nueva consulta a la BD ya que el filtro se realiza directamente sobre el AutoCompleteStringColletion y esta misma se carga una sola vez, que es al momento de Cargar el Form.
Sugiero no aplicar el AutoComplete con datos de tablas que contienen demasiados registros, ya que el tiempo de carga del Form podría verse sumamente afectado.
Creamos la Función de acceso a datos
  1:         /// <summary>
  2:         /// Obtiene informacion de la tabla especificada de la Bd y devuelve una lista generica de propiedaes
  3:         /// </summary>
  4:         /// <autor> Jose Luis Garcia Bautista </autor>
  5:         /// <returns>Lista Generica del tipo DataProperties</returns>
  6:         public static List<DataProperties> CargarDatos()
  7:         {
  8: 
  9:             //
 10:             // Declaramos una variable del tipo List<Of DataProperties> para cargar los datos recuperados de la BD
 11:             List<DataProperties> lista = new List<DataProperties>();
 12:             //
 13:             //Abrimos la conexión a nuestra Bd usando el archivo de configuracion App.Config
 14:             using (SqlCeConnection cnx = new SqlCeConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ToString()))
 15:             {
 16:                 //
 17:                 //Abrimos la conexión a la Bb
 18:                 cnx.Open();
 19:                 //
 20:                 //Creamos una variable constante para establecer la instruccion SQL
 21:                 const string sql = "SELECT * FROM Frutas ORDER BY Nombre ASC";
 22:                 //
 23:                 //Creamos el objeto Command propio del motor de BD que estemos usando en este caso SqlCeCommand
 24:                 SqlCeCommand cmd = new SqlCeCommand(sql, cnx);
 25:                 //
 26:                 //Creamos el objeto DataReader que se encargara de proporcionarnos las filas de datos obtenidas
 27:                 SqlCeDataReader dr = cmd.ExecuteReader();
 28:                 //
 29:                 // Preguntamos si el objeto DataReader correspondiente contiene datos
 30:                 while (dr.Read())
 31:                 {
 32:                     //
 33:                     //Instanciamos la clase contenedora de las propiedades para mepear los datos recuperados
 34:                     //de la BD
 35:                     DataProperties item = new DataProperties
 36:                     {
 37:                         //
 38:                         //Convertimos al tipo de dato correcto
 39:                         Id = Convert.ToInt32(dr["Id"]),
 40:                         Nombre = Convert.ToString(dr["Nombre"]),
 41:                     };
 42:                     //
 43:                     //Agregamos el nuevo item a la lista
 44:                     lista.Add(item);
 45:                 }
 46: 
 47:             }
 48:             //
 49:             //retornamos la lista 
 50:             return lista;
 51:         }

Llenamos el AutoCompleteStringCollection con los datos recuperados:
  1:         /// <summary>
  2:         /// Carga los item de una lista generica al objeto AutoCompleteStringCollection usado por algunos controles para
  3:         /// cumplir con la funcion AutoComplete
  4:         /// </summary>
  5:         /// <autor> Jose Luis Garcia Bautista </autor>
  6:         /// <returns>Regresa AutoCompleteStringCollection</returns>
  7:         public static AutoCompleteStringCollection LoadAutocomplete()
  8:         {
  9:             //
 10:             //Instanciamos el objeto que se usara para el AutoComplete
 11:             //
 12:             AutoCompleteStringCollection stringdata = new AutoCompleteStringCollection();
 13:             //
 14:             // llamamos a la funcion cargar datos para llenar la lista
 15:             //
 16:             _lista = CargarDatos();
 17: 
 18:             //
 19:             //Ejecutamos un ciclo foreach que recorrera item por item de la lista devuelta por CargarDatos()
 20:             //
 21:             foreach (DataProperties item in _lista)
 22:             {
 23:                 //
 24:                 //Por cada item encontrado obtenemos el valor de la propiedad Nombre y lo asignamos
 25:                 //a AutoCompleteStringCollection
 26:                 //
 27:                 stringdata.Add(Convert.ToString(item.Nombre));
 28:             }
 29:             //
 30:             //Devolvemos el AutoCompleteStringCollection con los datos cargados
 31:             //
 32:             return stringdata;
 33: 
 34:         }

Establecemos las propiedades del control TextBox :
  1:         /// <summary>
  2:         /// Se encarga de cargar el control TextBox con los datos de la lista
  3:         /// </summary>
  4:         /// <autor> Jose Luis Garcia Bautista </autor>
  5:         /// <param name="sender"></param>
  6:         /// <param name="e"></param>
  7:         private void Form1_Load(object sender, EventArgs e)
  8:         {
  9:             try
 10:             {
 11:                 //
 12:                 //Establecemos las propiedades del control TextBox
 13:                 //
 14:                 textBox1.AutoCompleteCustomSource = LoadAutocomplete();
 15:                 //
 16:                 //Para esta propiedad tenemos diferentes opciones (None, Suggest, Append, SuggestAppend)
 17:                 //para mayor documentacion 
 18:                 //http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=ES-ES&k=k(SYSTEM.WINDOWS.FORMS.AUTOCOMPLETEMODE.SUGGEST);k(SUGGEST);k(TargetFrameworkMoniker-%22.NETFRAMEWORK%2cVERSION%3dV4.0%22);k(DevLang-CSHARP)&rd=true
 19:                 //
 20:                 textBox1.AutoCompleteMode = AutoCompleteMode.Suggest;
 21:  
 22:                 textBox1.AutoCompleteSource = AutoCompleteSource.CustomSource;
 23:             }
 24:             catch (Exception er)
 25:             {
 26:                 //En caso de ocurrir alguna Excepcion atrapamos el mensaje y mostramos al usuario
 27:                 MessageBox.Show(string.Format("Error : {0}", er.Message), "Error inesperado", MessageBoxButtons.OK,
 28:                                 MessageBoxIcon.Error);
 29:             }
 30:         }
 31: 

Clase de propiedades:
  1: namespace AutoCompleteUsingListofT
  2: {
  3:     public class DataProperties
  4:     {
  5:         public int Id { get; set; }
  6:         public string Nombre { get; set; }
  7:     }
  8: }

En el ejemplo se utiliza una Bd SqlCompact V3.5 y Framework 4.0. En la siguiente entrada mostrare como enviar el valor del Id a un formulario padre.




2 comentarios:

  1. SALUDO JOSE LUIS , ME URGE PODER DESCARGAR EL EEJEMPLO EN VB .NET, ME AYUDAS?

    ResponderEliminar
    Respuestas
    1. Hola:

      Usa este link:

      https://1drv.ms/f/s!AiQ176xmckvhgS7B8fWrz2KQX9e6

      Saludos

      Eliminar

Deja un comentario si el articulo fue de utilidad.