【问题标题】:Disable WinForms ProgressBar animation禁用 WinForms ProgressBar 动画
【发布时间】:2010-05-14 14:12:03
【问题描述】:

是否可以禁用进度条的动画?

我需要它来处理一些暂停且目前未运行的进程。如果进度条在闪烁,一般用户会认为进程正在运行。

创建自己的进度条控件的建议不是我想要的。

【问题讨论】:

标签: c# .net winforms


【解决方案1】:

您可以使用 Vista 进度条的暂停状态,like this

// Assuming a Form1 with 3 ProgressBar controls
private void Form1_Load(object sender, EventArgs e)
{
  SendMessage(progressBar2.Handle,
    0x400 + 16, //WM_USER + PBM_SETSTATE
    0x0003, //PBST_PAUSED
    0);

  SendMessage(progressBar3.Handle,
    0x400 + 16, //WM_USER + PBM_SETSTATE
    0x0002, //PBST_ERROR
    0);
}

[DllImport("user32.dll", CharSet = CharSet.Unicode)]
static extern uint SendMessage(IntPtr hWnd,
  uint Msg,
  uint wParam,
  uint lParam);

【讨论】:

  • 这就是我想要的。谢谢你。那个项目很棒:windowsformsaero.codeplex.com
  • 我自己也遇到了同样的问题。不过有一个问题:该解决方案是否也适用于将在 XP 上运行的软件,还是仅适用于 Vista/Win7?
  • 链接导致页面丢失。最好在答案中复制和粘贴相关信息。
  • @SLaks 有没有办法在它是绿色的时候消除发光效果?
【解决方案2】:

我的解决方法是使用面板控件而不是 ProgressBar。我更改了 BackColor、BorderStyle(到 Fixed3D)并操纵它的 Width 以显示所需的进度级别。我假设 100% 的进度等于表单的宽度。

【讨论】:

    【解决方案3】:

    向用户传达操作已暂停或无法准确测量的标准方法是使用选取框显示样式。

    progressBar1.Style = ProgressBarStyle.Marquee;
    

    此样式忽略MaximumValue 属性并显示一个进度条“段”,该“段”不断在进度条上移动并循环(它不会填充进度条,它会移动看起来像一个部分的部分一直穿过控件,然后又回到开头。)

    【讨论】:

    • 谢谢。但我需要最大和价值。用户需要查看进程暂停的位置。
    • @Vasily:这是唯一独立于操作系统的程序;如果您保证 Vista 或 7,那么 SL​​ak 的答案应该可以解决您的问题。
    【解决方案4】:

    您要做的是专门设置此控件的样式以覆盖主题更改。这个article 为您提供了一些信息。

    【讨论】:

    【解决方案5】:

    您可以覆盖进度条的 OnPaint()。你实际上不需要重写整个东西,你只需要继承进度条并像这样覆盖 OnPaint:

    public class my_progress_bar : ProgressBar {
            public Brush brush;
            public my_progress_bar() {
                this.SetStyle(ControlStyles.UserPaint, true);
                brush = Brushes.ForestGreen;
            }
            protected override void OnPaint(PaintEventArgs e)
            {
                //base.OnPaint(e);
                Rectangle rectangle = e.ClipRectangle;
                rectangle.Width = (int)(rectangle.Width * ((double)Value / Maximum)) - 4;
                ProgressBarRenderer.DrawHorizontalBar(e.Graphics, e.ClipRectangle);
                rectangle.Height = Height - 4;
                e.Graphics.FillRectangle(brush, 2, 2, rectangle.Width, rectangle.Height);
            }
        }
    

    【讨论】:

    • 你误会e.ClipRectangle;这将无法正确呈现。此外,您还需要一个 Vista 风格的酒吧。致电ProgressBarRenderer.DrawHorizontalChunks 会更好一些。
    • e.ClipRectangle 是需要重绘的区域。你应该使用this.ClientRectangle
    • 正如我在我的问题中所说的“创建自己的进度条控件的建议不是我想要的。”
    • 这个答案是完全错误的。 OnPaint() 永远不会在进度条中调用,因为进度条是由 Windows (UxTheme.dll) 绘制的,而不是由 .NET 框架绘制的。
    【解决方案6】:

    将此粘贴​​为代码。这将重写进度条,它也可以自定义颜色。

    public class CProgressBar : ProgressBar
    {
    
    public Color MyColor {
        get { return _color; }
        set {
            _color = value;
            MyBrush = new SolidBrush(_color);
            Invalidate();
        }
    }
    
    private Color _color = Color.Green;
    
    public CProgressBar()
    {
        SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw, true);
    }
    
    public int Value {
        get { return _value; }
        set {
            _value = value;
            Invalidate();
        }
    }
    
    private int _value;
    
    private SolidBrush MyBrush = new SolidBrush(_color);
    
    protected override void OnPaint(PaintEventArgs e)
    {
        e.Graphics.FillRectangle(MyBrush, new Rectangle(0, 0, Width * (_value / Maximum), Height));
    }
    }
    

    【讨论】:

    • 顺便说一句,它正在工作。如果有人倒数,这意味着他太便宜了,不能自己尝试。
    • 我觉得你,只是投反对票甚至不说原因是非常粗鲁的。虽然使用.Net 4.5的时候代码有很多问题:class需要partial,MyBrush不能用非静态值初始化,最后什么都没画。我做错了什么?
    • Width * (_value / Maximum) 由于 int 转换而始终为零。
    猜你喜欢
    • 2013-09-03
    • 1970-01-01
    • 1970-01-01
    • 2012-05-26
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 2017-01-19
    • 1970-01-01
    相关资源
    最近更新 更多