Una buena interfaz gráfica debe ofrecer una experiencia de usuario satisfactoria, por esta razón cuando diseñamos una ventana o vista en la cual el usuario debe hacer una consulta, se lo podemos simplificar mucho mostrando los resultados de esta búsqueda a medida que va escribiendo. De forma similar a como se muestran las sugerencias cuando realizamos una búsqueda en Google.
Este mismo concepto de usabilidad web lo llevaremos a una aplicación WindowsForms con C#, el resultado será así:

Como requisito previo es fundamental que tu aplicación ya esté conectada a una base de datos y a sus respectivas tablas. En este ejemplo se usa Entity Framework. Conoce cómo conectar con una base de datos usando Entity Framework aquí.
Para poder conseguir este mismo resultado necesitaremos un TextBox y un DataGridView. El control TextBox no requiere ningún tipo de configuración especial. Sin embargo, si necesitamos ajustar varias propiedades del DataGridView para que todo luzca y funcione correctamente. (En el gif de arriba se pueden ver dos DataGridView, sin embargo solo nos interesa el que muestra los resultados mientras se escribe. El segundo es solo para mostrar datos relacionados con dicha búsqueda y puede ser reemplazado a conveniencia).
El valor Width del DataGridView debe ser el mismo que el valor Width del TextBox.
Propiedades a modificar del DataGridView:
- AllowUserToAddRows = False
- AllowUserToResizeRow = False
- AutoSizeColumnsMode = Fill
- BackgroundColor = White
- BorderStyle = FixedSingle
- CellBorderStyle = None
- ColumnHeadersVisible = False
- EditMode = EditProgrammatically
- EnableHeadersVisualStyle = False
- RowHeadersVisible = False
- RowTemplate > Height = (Cualquier valor de preferencia, pero se debe tener en cuenta ya que se usará en código)
- SelectionMode = FullRowSelect
- Visible = False
Para dotar de correcta funcionalidad a la lista desplegable debemos realizar varias acciones:
Programar en el evento TextChanged del TextBox una búsqueda a la base de datos para que se carguen los elementos en la lista desplegable. En este mismo evento haremos que el alto del DataGridView sea proporcional a las filas que se carguen según la búsqueda, es decir, que si por ejemplo al escribir devuelve cuatro resultados, la propiedad Height del DataGridView sea: Alto_de_Fila * 4. Hay que tener en cuenta que como la búsqueda es por aproximación, entre menos letras se digiten más resultados se mostrarán, así que también debemos definir un Height máximo para que este no se haga demasiado alto y no se salga de la pantalla (Para este ejemplo determiné un máximo equivalente a 15 filas).
private void TextBox_TextChanged(object sender, EventArgs e)
{
try
{
//CONSULTA A LA BASE DE DATOS
DataGridView.Visible = true;
using (miEntities datos = new miEntities())
{
var datosLista = from d in datos.mitabla
where d.campo1.Contains(TextBox.Text)
select new { d.campo1 };
DataGridView.DataSource = datosLista.ToList();
}
//QUITAR SELECCIÓN DE LA 1° FILA PARA NO CONFUNDIR AL USUARIO
DataGridView.Rows[0].Selected = false;
//ESTABLECEMOS LOS VALORES PARA AL ALTO DE FILA Y ALTO MÁXIMO
int minH = 32; //Tam .de 1 fila. Configurado en RowTemplate > Height a '32'
int maxH = 480; //32 por 15
int CantFilas = int.Parse(DataGridView.RowCount.ToString());
if (CantFilas > 15)
{
DataGridView.Height = maxH;
}
else
{
DataGridView.Height = minH * CantFilas;
}
}
catch { }
}
En el condicional que evalúa si el número de filas es mayor a 15, podemos poner otro valor de nuestra preferencia que vaya de acuerdo al tamaño de formulario donde se implementará la lista desplegable.
En el evento
KeyDown del
TextBox programamos
dos acciones asociadas a dos teclas. Si el usuario presiona
Tecla Direccional Abajo, el foco debe cambiar al
DataGridView y luego seleccionar la primera fila de este. Después programamos que al presionar
Tecla Escape el
DataGridView se haga invisible.
private void TextBox_KeyDown(object sender, KeyEventArgs e)
{
try
{
if (e.KeyData == System.Windows.Forms.Keys.Down)
{
DataGridView.Focus();
DataGridView.Rows[0].Selected = true;
}
else if (e.KeyData == System.Windows.Forms.Keys.Escape)
{
DataGridView = false;
e.Handled = e.SuppressKeyPress = true;
}
}
catch { }
}
La instrucción e.Handled = e.SuppressKeyPress = true; desactiva el evento KeyPress. Esto lo hacemos para desactivar el Beep del sistema que se ejecuta por defecto el presionar Escape.
Para que la lista desplegable sea funcional, es necesario que al seleccionar una de sus filas (ya sea presionando Enter o haciendo Clic) se realice una búsqueda con ese dato en otra tabla y luego se muestren dichos resultados en un segundo DataGridView. El valor de la fila seleccionada debe ser almacenado en una variable, la cual debe estar declarada en el ámbito global del formulario. Para este ejemplo la llamáremos Seleccionado de tipo string.
private void Buscar()
{
try
{
using (miEntities datos = new miEntities())
{
var datosLista = from d in datos.otraTabla
where d.campo1 == Seleccionado
select d;
SegundoDataGridView.DataSource = datosLista.ToList();
}
catch
{
}
TextBox.Text = Seleccionado; //COMPLETAMOS EL TEXTO BUSCADO
DataGridViewVisible = false;
SegundoDataGridView.Focus(); //ESTE CONTROL RECIBIRA EL RESULTADO DE LA BUSQUEDA
}
Se debe tener muy en cuenta como está establecida la relación de las tablas en la base de datos. En este ejemplo el valor buscado se encuentra en una tabla que sirve a modo de lista de todos los ítems a buscar. Luego hace una busqueda en una segunda tabla en la cual hay operaciones relacionadas con dicho ítem. Es decir, entre la tabla1 y la tabla2 hay una relación de 1 a muchos.
Para que lo anterior funcione, ahora es necesario programar unas acciones en los eventos SelectionChange, KeyDown, KeyPress y CellClic del DataGridView.
En el evento SelectionChange obtenemos el valor de la fila seleccionada y lo asignamos a la variable Seleccionado.
private void DataGridView_SelectionChanged(object sender, EventArgs e)
{
try
{
foreach (DataGridViewRow Filas in DataGridView.SelectedRows)
{
Seleccionado = DataGridView.Rows[Filas.Index].Cells[0].Value.ToString();
}
}
catch { }
}
En el evento KeyDown detectamos si la tecla presionada es Enter, y de ser así, ejecutamos el método Buscar(). Luego suprimimos el evento KeyPress.
private void DataGridView_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
Buscar();
e.SuppressKeyPress = true;
}
}
¿Por qué supimir el evento KeyPress? Por defecto el control DataGridView está programado para que al presionar Enter pase a la fila inmediatamente inferior. Si no desactivamos este evento lo que ocurrirá al intentar seleccionar un valor es que se busque el que está justo debajo. Es decir, que, si los resultados son Item1, Item2, Item3… y seleccionamos Item1, el método Buscar() recibirá de la variable Seleccionado el Item2. El control no cuenta con una propiedad que permita desactivar este comportamiento.
En el evento KeyPress detectamos si se presiona Tecla Escape, y de ser así, hacemos invisible el DataGridView y pasamos el foco al TextBox.
private void DataGridView_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == Convert.ToChar(Keys.Escape))
{
DataGridView.Visible = false;
TextBox.Focus();
}
}
Por último, en el evento Clic ejecutamos el método Buscar().
private void DataGridView_CellClick(object sender, DataGridViewCellEventArgs e)
{
Buscar();
}
Si quieres apoyarme económicamente para que siga creando contenido y podamos seguir aprendiendo juntos, en Ko-Fi puedes hacerlo.
¡Sí, quiero apoyarte!
Deja un comentario: