none
Ceros a la izquierda en un NumericUpDown RRS feed

  • Pregunta

  • Hola a todos los estimados foristas!

    Tengo una pregunta simple, pero que no logro resolver. Resulta que tengo un control NumericUpDown que usaré como cronómetro (para mostrar un conteo regresivo), así que quiero que me muestre el cero a la izquierda en las cifras menores a diez.

    ¿Hay alguna manera simple de hacerlo? O sea, quiero saber si hay alguna propiedad que me permita aplicar ese formato en el control de forma automática, de modo que no sea necesario escribir un código para insertar el cero. Yo estuve revisando pero no encontré nada.

    Desde ya les agradezco sus respuestas.


    INFORMACIÓN SIN LÍMITES... ¡Definitivamente el factor más maravilloso de la web!
    viernes, 27 de febrero de 2009 2:21

Respuestas

  • Hola, Jason:

    Los controles de usuario son un excelente recurso para salir de problemas (o para meterse en nuevos problemas, dependiendo de como quieras verlo).

    No estoy seguro de que esta solución trabaje. Pero por tratar que no quede.

    Primero, creas una nueva clase y pegas esto:

    Public Class myNUD  
        Inherits NumericUpDown  
        Private tx As TextBox  
     
        Public Sub New()  
            MyBase.New()  
            tx = New TextBox  
            MyBase.Controls.Add(tx)  
            With tx  
                .Left = -1  
                .Top = -1  
                .Height = Height  
                .Width = Width - 15  
                .Visible = True 
                .BringToFront()  
            End With 
            AddHandler tx.TextChanged, AddressOf UpdateBase  
        End Sub 
     
        Private Sub myNUD_Resize(ByVal sender As ObjectByVal e As System.EventArgs) Handles Me.Resize  
            With tx  
                .Height = Height  
                .Width = Width - 15  
                .BringToFront()  
            End With 
        End Sub 
     
        Private Sub myNUD_ValueChanged(ByVal sender As ObjectByVal e As System.EventArgs) Handles Me.ValueChanged  
            tx.Text = Format(MyBase.Value, "0000")  
        End Sub 
     
        Private Sub UpdateBase(ByVal sender As ObjectByVal e As EventArgs)  
            MyBase.Value = CDbl(tx.Text)  
        End Sub 
     
        Public Shadows Property Value() As Double 
            Get 
                Return MyBase.Value  
            End Get 
            Set(ByVal value As Double)  
                MyBase.Value = value  
                tx.Text = Format(value, "0000")  
            End Set 
        End Property 
     
    End Class 
     

    Luego abres el archivo "Designer" del formulario, y reemplazas todas las apariciones de "NumericUpDown" por "myNUD".

    Al heredar de NumericUpDown, cualquier cosa que el designer haga con el control, será compatible con el nuevo control, pero la presentación estará "sobreescrita" por el nuevo metodo.

    Claro, para que valga la pena usarlo, habría que agregar una propiedad "Formato" para que tengas más flexibilidad en la presentacion (en el ejemplo se usa incondicionalmente "0000"); también deberías filtrar los caracteres válidos en el TextBox, y tal vez adaptar el formato a otras propiedades del control base, como DecimalDigits, etc.

    Pero es un buen comienzo, y más simple que superponer a mano un TextBox en cada NUD seguramente es, y a fin de cuenta, son solo 40 líneas de código, incluyendo todas las declaraciones.


    Salud!
    domingo, 8 de marzo de 2009 22:24

Todas las respuestas

  • Hola,

    Puedes probar con algo como esto:

    protected override void OnValueChanged(EventArgs e) 
      base.OnValueChanged(e); 
     
      if (Value < 9) 
        Text = Value.ToString("00"); 
     
     

     

    Saludos 

     

     

     


    Leandro Tuttini
    viernes, 27 de febrero de 2009 16:05
  • Hola.

    Puedes probar también con la función padleft para rellenar con ceros.

    Un saludo.

    Javi.
    martes, 3 de marzo de 2009 20:38
  • Cómo están muchachos! Les agradezco sus respuestas. Según veo, no parece haber manera de hacerlo como yo quiero, o sea, con alguna configuración directa del control. Sé que un código me puede funcionar, pero es lo que quería evitar. No importa, tendrá que sr así. De todos modos aún no pruebo sus sugerencias; cuando lo haga les aviso que tal me va. A propósito, quisiera saber si Javier me puede especificar un poco cómo usar la función que me recomendó, pues soy nuevo programando en este lenguaje y desconozco el procedimiento. Si puedes, te lo agradezco Javier.
    INFORMACIÓN SIN LÍMITES... ¡Definitivamente el factor más maravilloso de la web!
    jueves, 5 de marzo de 2009 1:15
  • Hola,

    Javier se refiere a este metodo String.PadLeft Method

    Creo que tambien serviria, deberias usuarlo igualmente dentro del evento de change, algo asi:

    Text = Value.PadLeft(2, "0")


    Saludos


    Leandro Tuttini
    jueves, 5 de marzo de 2009 3:08
  • Leandro Tuttini dijo:

    Hola,

    Javier se refiere a este metodo String.PadLeft Method

    Creo que tambien serviria, deberias usuarlo igualmente dentro del evento de change, algo asi:

    Text = Value.PadLeft(2, "0")



    Hola,

    Es bueno probar las soluciones antes de recomendarlas.

    En un formulario, agregué un control Numeric UpDown y un botón.

    En el evento Click del botón escribí, simplemente:

    NumericUpDown1.Text = "01" (más simple no creo que se pueda hacer).

    y al darle al botón, el control muestra "1". Se ve que el control hace algo con el Change del TextBox que contiene.


    La única solución que veo es crear un control de usuario basado en un TextBox y en un VScrollBar (que tiene sus complicaciones, porque hay que invertir el sentido de las flechas... las VSB "crecen" hacia abajo), que soporte, además de las propiedades normales del NUD, la propiedad "Format", para poder presentar el valor como uno quiera.



    Salud!
    jueves, 5 de marzo de 2009 15:33
  • Hola,

    Quizá puedas hacer un pequeño truco, situa el control numérico y encima de este sitúas un cuadro de texto, de modo que sólo se vean las flechitas del control NumericUpDown, y el resto lo tape el cuadro de texto.

    Controlas el evento cuando cambie el valor del numericUpDown, recoges el valor, lo rellenas con los ceros con la función que te comenté (padLeft) y el resultado lo muestras en el cuadro de texto.

    Este truquillo, lo he utilizado para PDA's porque no se me ocurría nada mejor...

    Espero te sirva.

    Javi.

    • Propuesto como respuesta Javi_77 sábado, 7 de marzo de 2009 10:47
    jueves, 5 de marzo de 2009 19:37
  • Bueno amigos, no sé que piensen uds, pero yo opino que esa falla es un gran descuido de los creadores del VB, pues no veo que complicación podría tener agregarle esa propiedad a nuestro comentado control: NumerciUpDown. De verdad parece que ni por código se puede hacer lo que quiero, así que la solución tendrá que ser de verdad la última que sugerió el compañero Javier, que siendo francos no es la solución en sí! Jeje! Pero es una técnica o "truco" -como el mismo lo llamó- funcional en este caso.
    Con todo, aún no decido si usarla o no. Es que todo el resto del código ya lo creé aplicado a los NUD (que son nada menos que 6), por lo que sería bastante engorroso hacer todo ese cambio.

    De todos modos ya les avisaré lo que haga más adelante, aunque creo que habiendo analizado lo anterior debería dar por resuelta mi pregunta. No sé, ¿qué opinan uds? (Esperaré su opinión.)
    INFORMACIÓN SIN LÍMITES... ¡Definitivamente el factor más maravilloso de la web!
    jueves, 5 de marzo de 2009 23:56
  • Hola, Jason:

    Los controles de usuario son un excelente recurso para salir de problemas (o para meterse en nuevos problemas, dependiendo de como quieras verlo).

    No estoy seguro de que esta solución trabaje. Pero por tratar que no quede.

    Primero, creas una nueva clase y pegas esto:

    Public Class myNUD  
        Inherits NumericUpDown  
        Private tx As TextBox  
     
        Public Sub New()  
            MyBase.New()  
            tx = New TextBox  
            MyBase.Controls.Add(tx)  
            With tx  
                .Left = -1  
                .Top = -1  
                .Height = Height  
                .Width = Width - 15  
                .Visible = True 
                .BringToFront()  
            End With 
            AddHandler tx.TextChanged, AddressOf UpdateBase  
        End Sub 
     
        Private Sub myNUD_Resize(ByVal sender As ObjectByVal e As System.EventArgs) Handles Me.Resize  
            With tx  
                .Height = Height  
                .Width = Width - 15  
                .BringToFront()  
            End With 
        End Sub 
     
        Private Sub myNUD_ValueChanged(ByVal sender As ObjectByVal e As System.EventArgs) Handles Me.ValueChanged  
            tx.Text = Format(MyBase.Value, "0000")  
        End Sub 
     
        Private Sub UpdateBase(ByVal sender As ObjectByVal e As EventArgs)  
            MyBase.Value = CDbl(tx.Text)  
        End Sub 
     
        Public Shadows Property Value() As Double 
            Get 
                Return MyBase.Value  
            End Get 
            Set(ByVal value As Double)  
                MyBase.Value = value  
                tx.Text = Format(value, "0000")  
            End Set 
        End Property 
     
    End Class 
     

    Luego abres el archivo "Designer" del formulario, y reemplazas todas las apariciones de "NumericUpDown" por "myNUD".

    Al heredar de NumericUpDown, cualquier cosa que el designer haga con el control, será compatible con el nuevo control, pero la presentación estará "sobreescrita" por el nuevo metodo.

    Claro, para que valga la pena usarlo, habría que agregar una propiedad "Formato" para que tengas más flexibilidad en la presentacion (en el ejemplo se usa incondicionalmente "0000"); también deberías filtrar los caracteres válidos en el TextBox, y tal vez adaptar el formato a otras propiedades del control base, como DecimalDigits, etc.

    Pero es un buen comienzo, y más simple que superponer a mano un TextBox en cada NUD seguramente es, y a fin de cuenta, son solo 40 líneas de código, incluyendo todas las declaraciones.


    Salud!
    domingo, 8 de marzo de 2009 22:24