动画"焕发"所有者绘制进度条(ListView控件/ DataGridView中) [英] Animated "glow" in owner-drawn Progress Bar (ListView/DataGridView)

查看:123
本文介绍了动画"焕发"所有者绘制进度条(ListView控件/ DataGridView中)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到,在.NET 2.0(的WinForms)的沼泽标准进度并显示任人动画在Vista中发光棒;但是,使用ProgressBarRenderer(作为一个一般具有在试图绘制一个所有者绘制的列表视图一个进度条,网格视图,或其他这样的控制时),只是给没有pretty动画的视觉风格。

I've noticed that the bog-standard ProgressBar in .NET 2.0 (Winforms) does show up as the fancy animated glowing bar in Vista; however, using the ProgressBarRenderer (as one generally has to when trying to draw a progress bar in an owner-drawn list view, grid view, or other such control) just gives the visual style without the pretty animation.

我想这是愚蠢的期望,这将只是神奇的工作 - 我想在Vista中的本机控制必须有某种嵌入式定时器或线程显然绘制静态图像时不存在。我也看到,如果您连续重绘进度控制好几次(使用DrawToBitmap),你可以真正看到动画焕发出不同的阶段,所以我用一个定时器来自动保持重绘尝试的事,但只是不太对的外观,而且还吃了很多更多的CPU时间比实际进度呢。

I guess it was silly to expect that this would just magically work - I imagine the native control in Vista must have some sort of embedded timer or thread that obviously doesn't exist when drawing a static image. I did see that if you redraw a ProgressBar control several times in succession (using DrawToBitmap) that you can actually see the distinct stages of the animated glow, so I experimented with using a timer to keep redrawing automatically, but something's just not quite right about the look, and it also eats up a lot more CPU time than an actual ProgressBar does.

这似乎离开我与两个子标准选项:
a)使用ProgressBarRenderer并用Vista的看,但没有动画结束;要么
b)利用一个计时器不断重绘几个ProgressBars位图,和浪费CPU周期来让它看起来更好,但还不够完善。

This seems to leave me with two sub-standard options: a) Use the ProgressBarRenderer and end up with a Vista "look" but no animation; or b) Use a timer to continually redraw several ProgressBars to bitmaps, and waste CPU cycles to get it looking better but still not perfect.

我想知道是否有人有过经验的嵌入所有者绘制控件内的进度条,并可能知道的比上述两个选项一个更好的方式 - 这可以精确地再现闪烁/闪烁而不依赖定时器和/或锤击CPU。

I was wondering if anybody has had experience embedding progress bars inside owner-drawn controls and might know of a better way than the two options above - something that can accurately reproduce the glow/glint without relying on timers and/or hammering the CPU.

推荐答案

我不得不拉一些pretty疯狂的特技来完成这项工作。不幸的是,MSFT没更新VisualStyleElement.ProgressBar类补充说,Vista中添加的部分。和构造函数是私有的。而我在产生动画的部分猜测了一下。我相当接近这个code,它应该给你的东西来试验:

I had to pull some pretty crazy stunts to make this work. Unfortunately, MSFT didn't update the VisualStyleElement.ProgressBar class to add the parts that Vista added. And the constructor is private. And I had to guess a bit at the parts that produce the animation. I got fairly close with this code, it should give you something to experiment with:

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);
    }
  }

}

这篇关于动画"焕发"所有者绘制进度条(ListView控件/ DataGridView中)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆