Pergunta

Percebi que a barra de progresso padrão do pântano no .NET 2.0 (WinForms) aparece como a barra de animação animada sofisticada em Vista; No entanto, o uso do ProgressBarrenderer (como geralmente é necessário ao tentar desenhar uma barra de progresso em uma visualização de lista de proprietário, visualização da grade ou outro controle desse tipo), apenas fornece o estilo visual sem a bela animação.

Eu acho que era bobagem esperar que isso funcionasse magicamente - imagino que o controle nativo no Vista deve ter algum tipo de timer ou fio incorporado que obviamente não existe ao desenhar uma imagem estática. Eu vi que, se você redesenhou um controle da barra de progresso várias vezes em sucessão (usando drawTobitmap), você pode realmente ver os estágios distintos do brilho animado, então experimentei usar um cronômetro para manter o redesenho automaticamente, mas algo não está certo sobre A aparência, e também consome muito mais tempo da CPU do que uma barra de progresso real.

Isso parece me deixar com duas opções abaixo do padrão: a) Use o ProgressBarrenderer e acabar com um "visual" do Vista, mas sem animação; ou b) Use um cronômetro para redesenhar continuamente várias barras de progresso em bitmaps e desperdiçar ciclos da CPU para que pareça melhor, mas ainda não é perfeito.

Eu queria saber se alguém teve experiência em incorporar barras de progresso dentro dos controles desenhados do proprietário e poderia saber de uma maneira melhor do que as duas opções acima - algo que pode reproduzir com precisão o brilho/brilho sem depender de temporizadores e/ou martelar a CPU.

Foi útil?

Solução

Eu tive que puxar algumas acrobacias muito loucas para fazer isso funcionar. Infelizmente, o MSFT não atualizou a classe VisualStyleElement.ProgressBar para adicionar as peças que o Vista adicionou. E o construtor é privado. E eu tive que adivinhar um pouco as partes que produzem a animação. Eu cheguei bastante perto deste código, ele deve lhe dar algo para experimentar:

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
using System.Reflection;

namespace WindowsFormsApplication1 {
  public partial class Form1 : Form {
    VisualStyleElement pulseOverlay;
    VisualStyleElement moveOverlay;
    VisualStyleRenderer pulseRenderer;
    VisualStyleRenderer moveRenderer;
    Timer animator = new Timer();
    public Form1() {
      InitializeComponent();
      ConstructorInfo ci = typeof(VisualStyleElement).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance,
        null, new Type[] { typeof(string), typeof(int), typeof(int) }, null);
      pulseOverlay = (VisualStyleElement)ci.Invoke(new object[] { "PROGRESS", 7, 0 });
      moveOverlay = (VisualStyleElement)ci.Invoke(new object[] { "PROGRESS", 8, 0 });
      pulseRenderer = new VisualStyleRenderer(pulseOverlay);
      moveRenderer = new VisualStyleRenderer(moveOverlay);
      animator.Interval = 20;
      animator.Tick += new EventHandler(animator_Tick);
      animator.Enabled = true;
      this.DoubleBuffered = true;
    }
    void animator_Tick(object sender, EventArgs e) {
      Invalidate();
    }

    int xpos;
    protected override void OnPaint(PaintEventArgs e) {
      Rectangle rc = new Rectangle(10, 10, 100, 20);
      ProgressBarRenderer.DrawHorizontalBar(e.Graphics, rc);
      rc = new Rectangle(10, 10, 50, 20);
      ProgressBarRenderer.DrawHorizontalChunks(e.Graphics, rc);
      xpos += 3;
      if (xpos >= 30) xpos = -150;  // Note: intentionally too far left
      rc = new Rectangle(xpos, 10, 50, 20);
      pulseRenderer.DrawBackground(e.Graphics, rc);
      moveRenderer.DrawBackground(e.Graphics, rc);
    }
  }

}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top