TIP: Filtrar números en un campo de edición
Si uno quiere aplicar una máscara dentro de un campo de edición, tiene a su disposición el componente MaskEdit, que posee una propiedad llamada Mask y que, asignando ahí una serie de símbolos predefinidos, nos guiará a la hora de qué texto podemos introducir. Perfectamente válida en muchas situaciones, en otras es un engorro de lo más complicado, ya que, aunque la potencia del filtrado es enorme, a veces no nos permite una flexibilidad adecuada. En mi caso no he podido encontrar la máscara adecuada a la introducción de cualquier valor numérico entero sin tener problemas con los sombreados, los valores por defecto y un largo etcétera.
Por eso, siempre que necesito un campo numérico cualquiera sin formato, es decir, un campo que me permita introducir valores como "0", "33", "56789,89" de forma libre sin los problemas de la máscara -el que haya usado el componente sabrá a qué me refiero-, puede utilizar una técnica alternativa bastante sencilla.
Si tiene varios controles en una misma ficha que sólo permitan la introducción de valores numéricos, lo primero a realizar es seleccionar todos esos controles de edición de forma conjunta, irse a la ventana de propiedades y seleccionar la pestaña de eventos. Haciendo doble clic en el evento KeyDown obtendrá un manejador único para todos los controles seleccionados.
Otra forma consiste en, una vez generado dicho evento para un solo control, seleccionar uno a uno (o varios a la vez) los demás controles de edición y, en el mismo lugar que antes, abrir el desplegable del evento KeyDown y seleccionar el evento anterior.
Ya solo nos queda la edición del código que nos interesa. En mi caso, el código es:
void ConfigForm::EEditKeyDown(Object ^,KeyEventArgs^ e)
{
if(!
(
(e->KeyCode>=Keys::D0 && e->KeyCode<=Keys::D9)||
(e->KeyCode>=Keys::NumPad0 && e->KeyCode<=Keys::NumPad9)||
e->KeyCode==Keys::NumLock ||
e->KeyCode==Keys::Left ||
e->KeyCode==Keys::Right ||
e->KeyCode==Keys::Insert ||
e->KeyCode==Keys::Delete ||
e->KeyCode==Keys::Tab ||
e->KeyCode==Keys::Escape ||
e->KeyCode==Keys::OemPeriod ||
e->KeyCode==Keys::Back
)
)
e->SuppressKeyPress=true;
}
Básicamente estamos eliminando cualquier tecla que no se corresponda a las listadas. Las dos primeras líneas de la sentencia condicional miran si el valor introducido es un número, y las siguientes si se ha presionado dicha tecla especial. Como la sentencia está negada, el condicional sólo se ejecutará en el caso de que la tecla pulsada no sea ninguna de ellas.
Evidentemente, siempre podremos añadir o quitar las teclas que queramos a la lista.
Otra opción quizás más sencilla, es la de colocar todos los valores válidos dentro de un array estático dentro de la ficha (o incluso fuera de ella, en una clase propia) y realizar la comprobación mediante un bucle o incluso ordenar el array y utlizar el método BinarySearch junto a un predicado. Esa parte la deja el autor como ejercicio para el lector, y si éste tiene dudas para hacerlo, que me lo comunique y pondré una posible solución.
Y todavía podemos afinar más, mediante la realización de un componente que de alguna forma nos de la opción de elegir qué teclas permitimos (por ejemplo mediante un editor visual que nos permita marcar dichas teclas, o mediante una lista a la que podemos añadir/quitar elementos), pero aquí el autor considera que la ineficiencia del control (que llevaría mucho código sin utilizar), no supera la facilidad de uso; además, dicho control sería un ensamblado a acompañar a nuestra aplicación...