2011-05-20 27 views
13

estoy usando Windows Vista y Visual Studio 2010. Crear un .Net 4 Aplicación de Windows Forms. Coloque una barra de progreso en el formulario predeterminado, agregue código para manejar el evento de carga de formulario y haga allí un progressBar1.Value = 100;.ProgressBar es lenta en Windows Forms

Comience a depurar y vea una animación moviendo la barra de progreso a 100 en aproximadamente medio segundo.

necesito 2 barras de progreso en mi proyecto. Una es para "progreso global" y la segunda es para "progreso de paso actual", por lo que la segunda pasa de 0 a 100 y regresa a 0 para el siguiente paso. El problema es que con la barra de progreso siendo lenta para algunos de los pasos rápidos nunca llega a 100 y se ve raro.

¿Hay alguna manera de deshacerse de esa animación? En WPF está bien, pero preferiría quedarme con Windows Forms.

+0

intente llamar Application.DoEvents() método –

+0

no creo que es un problema de Windows Forms. Usé la barra de progreso muchas veces y siempre fue rápido. Verifique si algo más está frenando el rendimiento de su aplicación. – Vale

+0

Es un problema solo con la barra de progreso. Estoy usando un backgroud worker que informa progreso progresivo entre 0 y 100 con System.Threading.Thread.Sleep (10) entre cada valor. El controlador de eventos para el progreso del informe muestra el valor del progreso en un cuadro de texto y en la barra de progreso. El cuadro de texto va de 0 a 100, la barra de progreso va de 0 a aproximadamente 70. – user755327

Respuesta

14

esto es sólo la forma en la barra de progreso Vista/7 está diseñado. Cuando cambia el valor de la barra de progreso, la barra se anima progresivamente a ese valor.

El único modo que conozco de evitar este problema es ir hacia atrás cuando la actualización de la barra de progreso, de la siguiente manera:

progressBar1.Value = n; 
if (n>0) 
    progressBar1.Value = n-1; 

Para una discusión más completa ver Disabling .NET progressbar animation when changing value?

+0

Tendré que verificar pero Creo que la barra de progreso también fue más lenta que el cuadro de texto en Windows XP. Así que WPF o lidiar con eso, está bien. – user755327

+0

@user Estoy 100% seguro de que esta es la respuesta. WPF dibuja todos sus propios controles y no usa controles Win32. WinForms cierra los controles de Win32. Consulte http://stackoverflow.com/questions/5332616/disabling-net-progressbar-animation-when-changing-value –

+0

Está bien. Solo quería decir que tendré que consultar con Windows XP, recuerdo que la barra de progreso es "más lenta" que el cuadro de texto. – user755327

2

Usted puede escribir una costumbre barra de progreso para mostrar su valor sin animación. La siguiente es una aplicación sencilla para mostrar el progreso de 0 a 100 y volver a 0.

public class ProgressBarDirectRender : UserControl 
{ 
    private int _value; 
    public int Value 
    { 
     get { return _value; } 
     set 
     { 
      if (value < 0 || value > 100) 
       throw new ArgumentOutOfRangeException("value"); 
      _value = value; 
      const int margin = 1; 
      using (var g = CreateGraphics()) 
      { 
       if (_value == 0) 
        ProgressBarRenderer.DrawHorizontalBar(g, ClientRectangle); 
       else 
       { 
        var rectangle = new Rectangle(ClientRectangle.X + margin, 
                ClientRectangle.Y + margin, 
                ClientRectangle.Width * _value/100 - margin * 2, 
                ClientRectangle.Height - margin * 2); 
        ProgressBarRenderer.DrawHorizontalChunks(g, rectangle); 
       } 
      } 
     } 
    } 
    protected override void OnPaint(PaintEventArgs e) 
    { 
     base.OnPaint(e); 
     ProgressBarRenderer.DrawHorizontalBar(e.Graphics, ClientRectangle); 
    } 
} 
+0

Buena idea, pero no funciona si quieres ir " al revés "(Tal vez porque esto no era necesario en la pregunta) Sugeriría habilitar el doble buffer, mover todo el dibujo a OnPaint y simplemente invalidar en el setter. Pero esta fue una buena pista para mí y ahora todo funciona perfecto :) – drvolcano

9

edificio fuera de Heffernan's tip en ir hacia atrás con la barra de progreso y Reinhart's extension method approach en una pregunta relacionada, vine con mi propia solución.

La solución es bastante perfecta y maneja con éxito el problema que encontrará cuando el valor esté en Maximum. Este método de extensión a ProgressBar alivia la retraso que se produce desde el estilo de animación progresiva presentes en los WinFormsProgressBar control cuando se ejecuta en Windows Vista y 7 (no he probado en Windows 8 aún).

public static class ExtensionMethods 
{ 
    /// <summary> 
    /// Sets the progress bar value, without using 'Windows Aero' animation. 
    /// This is to work around a known WinForms issue where the progress bar 
    /// is slow to update. 
    /// </summary> 
    public static void SetProgressNoAnimation(this ProgressBar pb, int value) 
    { 
     // To get around the progressive animation, we need to move the 
     // progress bar backwards. 
     if (value == pb.Maximum) 
     { 
      // Special case as value can't be set greater than Maximum. 
      pb.Maximum = value + 1;  // Temporarily Increase Maximum 
      pb.Value = value + 1;  // Move past 
      pb.Maximum = value;   // Reset maximum 
     } 
     else 
     { 
      pb.Value = value + 1;  // Move past 
     } 
     pb.Value = value;    // Move to correct value 
    } 
} 

Ejemplo de uso:

private void backgroundWorker_ProgressChanged(object sender, 
                ProgressChangedEventArgs e) 
{ 
    progressBar.SetProgressNoAnimation(e.ProgressPercentage); 
} 
+0

Honestamente, 'pb.Value = value;' al final puede estar dentro del 'else'; reducir el máximo mientras el valor está al máximo automáticamente reduce el valor de todos modos. – Nyerguds