miércoles, 6 de febrero de 2008

ComboBox en Visual Studio 2005

Cuando estás acostumbrado a hacer las cosas de una forma, suele costar un poco cambiar la mentalidad y hacerlas de otra distinta. Independientemente de que ésta nueva forma sea mejor o más cómoda.

Cualquiera que haya tratado con los famosos ComboBox -en algunos libros se traduce como cajas desplegables- ha podido utilizar esa característica mediante la cual no puedes escribir en él -se suele decir que el estilo es DropDownList- pero si pulsas varias teclas, se posiciona en el elemento cuyo comienzo corresponde con ese inicio.

Ahora las cosas han cambiado, y esto ya no funciona así en Visual Studio 2005. En esta versión, la herramienta de desarrollo de Microsoft ignora las teclas que has pulsado previamente, y sólo se queda con la última, seleccionando el primer elemento que comienza con esa letra -o número-.

Esto descoloca al más pintado, que con la incredulidad todavía pintada en la cara se pone a buscar una solución por el basto mundo de los foros de ayuda. Y la solución por llamarle de alguna forma está en esta nota del Soporte Técnico. Lo mejor de todo es la explicación oficial de la causa, que viene a ser literalmente:

This problem occurs because the ComboBox search is based on one character instead of the complete character set.

O utilizando la herramienta de traducción de la misma página:

Este problema se debe a la búsqueda ComboBox basarse en un carácter en vez del juego de caracteres completo.

Pensarás genial, si está encontrada la causa, ahora sólo queda poner un remedio. Pero no, resulta que la solución que propone el mismo documento técnico es la utilización de un Timer, el evento KeyUp del ComboBox y un código que funciona fatal y crea un efecto visual como para echar la pota. Así, al más puro estilo Pepe Gotera y Otilio.

Hasta aquí la crítica a la chapuza. Ahora pasamos a la solución de verdad, y es que la gente de Microsoft ha decidido que esto ya no se hace así, sino con otras dos nueva propiedades y una forma de trabajar muy distinta. Estoy hablando de:

AutoCompleteMode = SugestAppend
AutoCompleteSource = ListItems

La primera propiedad va mostrando los valores que coinciden (de la misma forma que funciona la barra de direcciones de Firefox o Internet Explorer) al mismo tiempo que completa el texto con la primera coincidencia (hay otras dos opciones igual de válidas, pero a mi me gusta ésta). La segunda propiedad dice que la lista de valores posibles para “autocompletar” son los propios Items del ComboBox.

El único problema es que así no te aseguras de que te han elegido un elemento de la lista -imaginemos que no permitimos la iniciativa individual -. Así, no nos quedará otra opción que incluir en el evento Leave del ComboBox un código más o menos como este:

if (comboBox1.Text != "") && (comboBox1.Items.IndexOf(comboBox1.Text) == -1)
{
MessageBox.Show("El valor elegido no está en la lista.");
comboBox1.Focus();
}


Por cierto, en el código anterior he puesto comboBox1 para facilitar su lectura y comprensión. Lo ideal es poner en su lugar (sender as ComboBox), ya que de esta forma el mismo código sirve para todos los eventos Leave de todos los ComboBox, consiguiendo así ese mito de la reutilización.

Esta es la forma que he encontrado para hacerlo, pero si estás leyendo esto y sabes otra mejor, por favor, no dudes en decírmelo.

2 comentarios:

Anónimo dijo...

HOLA!
Llevo varios días inentando posicioanrme en un Dropdownlist pero.... es una locura! He intentado seguir tu ejemplo pero me da el siguiente error:'AutoCompleteMode' no es un miembro de 'System.Web.UI.WebControls.DropDownList'.

Como puedo solucionarlo?
Trabajo con Visual Studio y Webmatrix
Gracias y saludos

osaez@matholding.com

JoseMa Perez dijo...

Muy buenas


Es verdad, el post que puse es únicamente para WindowsForm. Me temo que no es aplicable a la parte Web.

Me parece que el WebControl funciona "a la vieja usanza", es decir, el control ya se posiciona en el elemento que coincide con las teclas pulsadas (por lo menos acabo de hacer una prueba tonta y ha funcionado bien).

En VS2005 no veo otra forma de hacerlo, siento no poder ayudarte mucho mas...


Un saludo.