Problema con Progress Bar: El valor de '101' no es válido para 'Value'.

Iniciado por z3nth10n, 1 Agosto 2013, 15:51 PM

0 Miembros y 2 Visitantes están viendo este tema.

z3nth10n

Hola buenas, pues este error sucede cuando hago un Progress Bar falso:

Código (vbnet,1,8) [Seleccionar]
Dim WithEvents Timer1 As New Timer With {.Interval = 1}

   Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
       Timer1.Enabled = True
   End Sub

   Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
       ProgressBar1.Value += 1
   End Sub


Estoy intentando entender los procesos y eventos del progress bar, y por lo que me parece, es cosa del Tick del Timer1 que al tener un Interval tan reducido se come por completo el Value del Progress Bar (es como si no le diese tiempo a escribir 1 en el mismo Tick y escribese 2 o más "1" en el Value del PB)...

Que puedo hacer? A parte de aumentarle el Interval? :huh:

Un saludo.

Interesados hablad por Discord.

Eleкtro

#1
Cita de: Ikillnukes en  1 Agosto 2013, 15:51 PM
Estoy intentando entender

Pues te lo explico de forma sencilla:

La barra de progreso tiene un rango, ese rango se utiliza para medir el progreso (llenar la barra), no puedes aumentar el valor infinítamente porque sinó la barra de progreso no sabría cuando se debe rellenar por completo... es obvio.

El rango por defecto es de 0-100, NUNCA puedes sobrepasar ese rango (por eso te salta error), pero si que puedes modificar el rango, por ejemplo de 0 a 10, o de 5 a 50, eso depende de tus necesidades (Leete las propiedades del control para ver la propiedad que debes modificar...).

Esto sería la solución a lo que intentas hacer:

Código (vbnet,16,17) [Seleccionar]
Public Class Form1

   Dim WithEvents Timer1 As New Timer With {.Interval = 10, .Enabled = True}

   Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
       InfiniteProgressBar(ProgressBar1)
   End Sub

   Private Sub InfiniteProgressBar(ByVal ProgressBar As ProgressBar, _
                                   Optional value As Int32 = 1)

       Select Case ProgressBar.Value

           Case Is < ProgressBar.Maximum
               ProgressBar.Value += value
           Case Is >= ProgressBar.Maximum ' Si el valor es igual o mayor que el valor máximo del rango...
               ProgressBar.Value = ProgressBar.Minimum ' Seteamos el valor mínimo (0) a la barra de progreso...

       End Select

   End Sub

End Class








z3nth10n

Lol, ahora no me salta ninguna Excepción, pero cuando llega a su tope vuelve a empezar XD Voy a ver las properties del Progress Bar y te cuento. :laugh:

Interesados hablad por Discord.

1mpuls0

Cita de: Ikillnukes en  1 Agosto 2013, 18:56 PM
Lol, ahora no me salta ninguna Excepción, pero cuando llega a su tope vuelve a empezar XD Voy a ver las properties del Progress Bar y te cuento. :laugh:


:huh:
Creo que el nombre del método InfiniteProgressBar no dice mucho.

y esto tampoco.

Código (vbnet) [Seleccionar]

Case Is >= ProgressBar.Maximum ' Si el valor es igual o mayor que el valor máximo del rango...
               ProgressBar.Value = ProgressBar.Minimum ' Seteamos el valor mínimo (0) a la barra de progreso...
abc

z3nth10n

No digo que no sea incorrecto, lo único que no llega al tope de la barra (es decir se queda a la mitad y vuelve a empezar, antes me saltaba una excepción cuando llegaba a ese punto... ) :P
PD: Sigo haciendo hincapié en que es problema del Timer... :P

A lo mejor, si lo con un Do Until... :P Ara pruebo a ver.. ;)

Interesados hablad por Discord.

1mpuls0

Cita de: Ikillnukes en  1 Agosto 2013, 18:56 PM
Lol, ahora no me salta ninguna Excepción, pero cuando llega a su tope vuelve a empezar XD Voy a ver las properties del Progress Bar y te cuento. :laugh:

Cita de: Ikillnukes en  1 Agosto 2013, 19:22 PM
No digo que no sea incorrecto, lo único que no llega al tope de la barra (es decir se queda a la mitad y vuelve a empezar, antes me saltaba una excepción cuando llegaba a ese punto... ) :P

:¬¬ quién te entiende.

El código actual es lo que publicaste en tu primer comentario más la modificación del código de EleKtro H@cker???
abc

WHK

Eso quiere decir que estas sacando mal el calculo del valor actual del progressbar.

Recuerda que el valor máximo es 100 y está por porcentajes.

Digamos que tienes 5 manzanas de 200, entonces tienes un 2.5% de todas las manzanas, nunca llegarás al 101%.

200 = 100%
5     = x%

((5 * 100) / 2) = 2.5%


Puedes arreglarlo diciendo que si el valor es mayor que 100 entonces que el valor vuelva a 100 pero estarias dando una información no exacta y falsa sobre tu progressbar porque cuando diga que lleva 30% a lo mejor van a ser 20% reales.

Además no deberias usar un timer, debes usar eventos, donde cada ves que se quiera establecer un valor entonces haga todo el cambio, para eso debes crear un "Control de usuario" y desde ahi crear la función setValue donde le indiques el valor y en ese momento que cambie la barra.

Que sucede si abusas del timer?... si haces un timer muy rapido y la barra no se ha movido en 5 minutos entonces tendras un uso de CPU bastante considerable sin hacer nada, mientra mas rapido sea el timer mas CPU va a utilizar, en cambio con los eventos podras hacer que se cambie solamente cuando se establezca un valor.

z3nth10n

CitarAdemás no deberias usar un timer, debes usar eventos, donde cada ves que se quiera establecer un valor entonces haga todo el cambio, para eso debes crear un "Control de usuario" y desde ahi crear la función setValue donde le indiques el valor y en ese momento que cambie la barra.

Que sucede si abusas del timer?... si haces un timer muy rapido y la barra no se ha movido en 5 minutos entonces tendras un uso de CPU bastante considerable sin hacer nada, mientra mas rapido sea el timer mas CPU va a utilizar, en cambio con los eventos podras hacer que se cambie solamente cuando se establezca un valor.

Interesante ::) Voy a ver lo que encuentro por ahí, gracias WHK ;)

Interesados hablad por Discord.

Eleкtro

#8
...Ikillnukes, el código que puse es 100% funcional, de echo es fácil de entender y se puede apreciar a simple vista que no puede haber error alguno en las condiciones que usé.

Lo que te sucede de que la barra llega a la mitad y no sube, pero ves como vuelve a empezar el Filling ...pues la razón es muy simple, lo que sucede es que al no usar otro hilo para rellenar la barra, todas las instrucciones se hacen en el mismo hilo y la barra de progreso no da a basto a la hora de rellenarse, pintarse, y refrescarse, debes refrescar manuálmente el control para mostrar los cambios con un "progressbar1.refresh" o un "invalidate" después de modificar el valor de la barra...en cada ocasión.

...en resumen, tu crees que no se llena la barra, pero en realidad se llena, sólo que no se muestra rellenada, eso pasa siempre con las progressbar sin hilo (aunque en el code que te puse a mi no me pasa, así que quizás también influya la velocidad del PC).

Ya te dije que para usar barras de progresos tienes que introducirte en el tema del multi hilo (multi-threading), busca ejemplos de progressbars con threads o con backgroundworkers en Google, porque hay miles.

Una barra de progreso sin un thread es una chapuza muy grande, ya que ralentiza globálmente el Form, y bastante.

Un saludo








SγиtαxEяяoя

Y que tal si yo doy mi aporte  :rolleyes:

Código (vbnet) [Seleccionar]

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Timer1.Start()
        Label1.Text = ("Working")
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
       
        If ProgressBar1.Value < ProgressBar1.Maximum Then
            ProgressBar1.Value += 1
        Else
            ProgressBar1.Value = ProgressBar1.Minimum = 99
            Timer1.Stop()
            Label3.Text = ("Success")
'Aqui puedes agregar algún evento, algo como mostrar un Form al completar la barra al 100%
'Siempre la barra se resetea a 0% cuando llega a su tope, y no se reinicia
        End If
    End Sub


Espero que te funcione :)