O por que sale una , en vez de . cuando uso toString("0000.00")
Si esta programando una interfaz grafica en C# muy probablemente habra necesitado hacer un textBox que formatee los datos en el, ya sabe agregando ceros a la izquierda y poniendo los decimales.
En C# basta con aprovechar el evento "Leave" para que, al momento que el cuadro de texto (referido de aquí en adelante como TextBox) lea el contenido, se convierta en numero y luego usar .toString("00000.00") para dar el formato necesario, fácil, ¿no?
Pues NO
En C# basta con aprovechar el evento "Leave" para que, al momento que el cuadro de texto (referido de aquí en adelante como TextBox) lea el contenido, se convierta en numero y luego usar .toString("00000.00") para dar el formato necesario, fácil, ¿no?
Pues NO
Al menos en C# existe un detalle capaz de causar errores impredecibles, calculos errados
y un dolor de cabeza buscando que salio mal, y cuya única pista parece ser que el textBox esta ignorando el punto decimal.
Todo esto resultado de una buena idea que tal
vez podría estar o mejor explicada o mejor implementada.
Ejemplo en acción.
Para explicar esto usaremos un programa muy sencillo, simplemente recibe un numero
en un textbox y al pulsar un boton calcula y muestra el cuadrado de este en otro textBox
como muestra la figura 1
Figura 1 - Aplicación de Ejemplo. |
Y que al poner un numero lo formatee de modo que ponga los ceros a la izquierda y la derecha necesarios, como
muestran la Figuras 2 y 3
Figura 2 - Entrada de Datos. |
Figura 3 - Formato de Datos. |
(Ya en la figura 3 puede empezar a notar que algo anda mal, llegare a eso en un momento)
Ese formateo se logra con el evento Leave del textBox, asumire que ya sabe como declararlo, el codigo que use
para dar formato es el siguiente:
private void textBox1_Leave(object sender, EventArgs e)
{
double d = Convert.ToDouble(textBox1.Text);
textBox1.Text = d.ToString("0000.00");
}
y para el botón se usa este código, de nuevo nada del otro mundo
private void button1_Click(object sender, EventArgs e)
{
double d = Convert.ToDouble(textBox1.Text);
d = d * d;
textBox2.Text = d.ToString("0000.00");
}
Suena simple pasamos el texto a double y luego ese double lo pasamos a texto aplicandole el formato deseado, incluso puede ver que pusimos un punto para indicar donde iran los decimales.
Como puede ver en la figura 2 se puso un 45.5 en el textBox1, pero al pulsar fuera del textoBox1 vemos el 45.5 convertise en un 0455.00 como en la figura 3 y al pulsar el boton btenermos el cuadrado de ese numero, pero *no* del que pusimos Figura 2
private void textBox1_Leave(object sender, EventArgs e)
{
double d = Convert.ToDouble(textBox1.Text);
textBox1.Text = d.ToString("0000.00");
}
y para el botón se usa este código, de nuevo nada del otro mundo
private void button1_Click(object sender, EventArgs e)
{
double d = Convert.ToDouble(textBox1.Text);
d = d * d;
textBox2.Text = d.ToString("0000.00");
}
Suena simple pasamos el texto a double y luego ese double lo pasamos a texto aplicandole el formato deseado, incluso puede ver que pusimos un punto para indicar donde iran los decimales.
Como puede ver en la figura 2 se puso un 45.5 en el textBox1, pero al pulsar fuera del textoBox1 vemos el 45.5 convertise en un 0455.00 como en la figura 3 y al pulsar el boton btenermos el cuadrado de ese numero, pero *no* del que pusimos Figura 2
Figura 4 - Resultado erroneo. |
La unica pista que tenemos sale de la documentacion de .NET donde se refieren a un parametro del metodo toString de tipo CultureInfo
el cual es la clave de lo que esta pasando aqui.
Al parecer, con el propósito de facilitar la localización de los programas, C# permite indicar como se deben separar los números, y otros valores dependiente de localidad esto es recordando que en algunos idiomas la , se usa (quien sabe por que) para indicar decimales y esto se puede demostrar en el programa ejemplo pues si escribe 45,5 en el programa (Figura 5), consigue el resultado correcto (Figura 6).
el cual es la clave de lo que esta pasando aqui.
Al parecer, con el propósito de facilitar la localización de los programas, C# permite indicar como se deben separar los números, y otros valores dependiente de localidad esto es recordando que en algunos idiomas la , se usa (quien sabe por que) para indicar decimales y esto se puede demostrar en el programa ejemplo pues si escribe 45,5 en el programa (Figura 5), consigue el resultado correcto (Figura 6).
Figura 5 - 45,5 |
Figura 6 - Resultado usando comas. |
Pero como aquí *no* se usa la coma para los decimales que el programa se comporte de ese modo es molesto, por decir de menos , sin mencionar que puede ser
desconcertante que el programa *no* este haciendo lo que se le indica en el codigo.
Por fortuna la solucion es sencilla basta agregar al inicio del programa la instrucción
Por fortuna la solucion es sencilla basta agregar al inicio del programa la instrucción
using System.Globalize;
y el parametro "CultureInfo.InvariantCulture" al toString y al
Convert.toDouble y listo, el punto decimal hará honor a su nombre y funcionara se espera.
Figura 7 - Programa corregido |
Figura 8 - Comportamiento correcto. |
Para hacer esto mas claro aquí esta el código con las correcciones, el parámetro "CultureInfo.InvariantCulture" se encarga de indicar a la función de hacer exactamente lo que se le dice, sin tomar en cuenta detalles sobre el idioma del sistema.
{
double d = Convert.ToDouble(textBox1.Text, CultureInfo.InvariantCulture);
d = d * d;
textBox2.Text = d.ToString("0000.00", CultureInfo.InvariantCulture);
}
private void textBox1_Leave(object sender, EventArgs e)
{
double d = Convert.ToDouble(textBox1.Text, CultureInfo.InvariantCulture);
textBox1.Text = d.ToString("0000.00", CultureInfo.InvariantCulture);
}
Espero que esto sea de ayuda para los que se encuentren con este tipo de problemas.
No hay comentarios:
Publicar un comentario