如何在C#.NET 3.5中更改进度条的颜色?

Iva*_*nov 84 .net c# .net-3.5 winforms

我想在进度条上做两件事.

  1. 将绿色更改为红色.
  2. 取出块并使其成为一种颜色.

关于我想知道如何完成的这两件事的任何信息将非常适合!

谢谢.

use*_*613 110

好的,我花了一段时间阅读所有的答案和链接.这是我从他们那里得到的:

样本结果

接受的答案会禁用视觉样式,它允许您将颜色设置为您想要的任何颜色,但结果看起来很简单:

在此输入图像描述

使用以下方法,您可以获得以下内容:

在此输入图像描述

如何

首先,如果您还没有: using System.Runtime.InteropServices;

其次,您可以创建此新类,也可以将其代码放入现有的static非泛型类中:

public static class ModifyProgressBarColor
{
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
    static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr w, IntPtr l);
    public static void SetState(this ProgressBar pBar, int state)
    {
        SendMessage(pBar.Handle, 1040, (IntPtr)state, IntPtr.Zero);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,要使用它,只需调用:

ModifyProgressBarColor.SetState(progressBar1, 2);

注意SetState中的第二个参数,1 =正常(绿色); 2 =错误(红色); 3 =警告(黄色).

希望能帮助到你!

  • 你创建了一个扩展方法,所以调用应该是progressBar1.SetState(2); 除此之外,很棒的答案! (17认同)
  • 需要注意的是,这仅适用于Vista +.您可以通过搜索[PBM_SETSTATE](http://msdn.microsoft.com/en-us/library/windows/desktop/bb760850(v = vs.85).aspx)查看完整文档. (4认同)

Cri*_*spy 78

由于之前的答案似乎不适用于Visual Styles.您可能需要创建自己的类或扩展进度条:

public class NewProgressBar : ProgressBar
{
    public NewProgressBar()
    {
        this.SetStyle(ControlStyles.UserPaint, true);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        Rectangle rec = e.ClipRectangle;

        rec.Width = (int)(rec.Width * ((double)Value / Maximum)) - 4;
        if(ProgressBarRenderer.IsSupported)
           ProgressBarRenderer.DrawHorizontalBar(e.Graphics, e.ClipRectangle);
        rec.Height = rec.Height - 4;
        e.Graphics.FillRectangle(Brushes.Red, 2, 2, rec.Width, rec.Height);
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:更新了代码,使进度条使用背景的视觉样式

  • 我意识到这已经老了; 我意识到这是一个尼特(因为最低几乎总是零); 但宽度比例因子应为**(((双倍)值 - (双倍)最小值)/((双倍)最大值 - (双倍)最小值))**以保持正确的方式.:) (3认同)
  • 多亏了这一点,我可以在我的解决方案中使用它. (2认同)

Wil*_*iel 33

这是最常被接受的代码的无闪烁版本,您可以找到这个问题的答案.所有归功于那些顽固答案的海报.谢谢Dusty,Chris,Matt和Josh!

就像其中一条评论中的"Fueled"的要求一样,我还需要一个表现得更专业的版本......专业.此代码维护样式,如前面的代码,但添加了屏幕外图像渲染和图形缓冲(并正确处理图形对象).

结果:一切都好,没有闪烁.:)

public class NewProgressBar : ProgressBar
{
    public NewProgressBar()
    {
        this.SetStyle(ControlStyles.UserPaint, true);
    }

    protected override void OnPaintBackground(PaintEventArgs pevent)
    {
        // None... Helps control the flicker.
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        const int inset = 2; // A single inset value to control teh sizing of the inner rect.

        using (Image offscreenImage = new Bitmap(this.Width, this.Height))
        {
            using (Graphics offscreen = Graphics.FromImage(offscreenImage))
            {
                Rectangle rect = new Rectangle(0, 0, this.Width, this.Height);

                if (ProgressBarRenderer.IsSupported)
                    ProgressBarRenderer.DrawHorizontalBar(offscreen, rect);

                rect.Inflate(new Size(-inset, -inset)); // Deflate inner rect.
                rect.Width = (int)(rect.Width * ((double)this.Value / this.Maximum));
                if (rect.Width == 0) rect.Width = 1; // Can't draw rec with width of 0.

                LinearGradientBrush brush = new LinearGradientBrush(rect, this.BackColor, this.ForeColor, LinearGradientMode.Vertical);
                offscreen.FillRectangle(brush, inset, inset, rect.Width, rect.Height);

                e.Graphics.DrawImage(offscreenImage, 0, 0);
                offscreenImage.Dispose();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


dus*_*ell 27

在设计器中,您只需将ForeColor属性设置为您想要的任何颜色.在红色的情况下,它有一个预定义的颜色.

要在代码(C#)中执行此操作:

pgs.ForeColor = Color.Red;
Run Code Online (Sandbox Code Playgroud)

编辑:哦是的,还将Style设置为连续.在代码中,像这样:

pgs.Style = System.Windows.Forms.ProgressBarStyle.Continuous;
Run Code Online (Sandbox Code Playgroud)

另一个编辑:您还需要删除Application.EnableVisualStyles()从您Program.cs(或类似)读取的行.如果你不能这样做,因为你希望应用程序的其余部分具有视觉样式,那么我建议你自己绘制控件或继续使用WPF,因为这样的事情很容易用WPF.您可以找到有关所有者在codeplex上绘制进度条的教程

  • 呸......好吧,我看到了问题.您需要禁用视觉样式才能使其与属性一起使用.它可能使用您选择的任何主题进行绘画.在Program.cs中有一行读取Application.EnableVisualStyles().删除该行,这将工作.否则,您需要自己绘制控件.另一种选择是使用WPF(如果它是可能的话),因为它可以让你很容易地做这种事情. (3认同)
  • Forecolor =红色; 背景色=蓝色; 风格=持续.没有什么改变,它的停留就像我从来没有碰过它 (2认同)

Jos*_* M. 15

使用Matt Blaine和Chris Persichetti的答案我创建了一个看起来更好的进度条,同时允许无限的颜色选择(基本上我在Matt的解决方案中更改了一行):

ProgressBarEx:

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace QuantumConcepts.Common.Forms.UI.Controls
{
    public class ProgressBarEx : ProgressBar
    {
        public ProgressBarEx()
        {
            this.SetStyle(ControlStyles.UserPaint, true);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            LinearGradientBrush brush = null;
            Rectangle rec = new Rectangle(0, 0, this.Width, this.Height);
            double scaleFactor = (((double)Value - (double)Minimum) / ((double)Maximum - (double)Minimum));

            if (ProgressBarRenderer.IsSupported)
                ProgressBarRenderer.DrawHorizontalBar(e.Graphics, rec);

            rec.Width = (int)((rec.Width * scaleFactor) - 4);
            rec.Height -= 4;
            brush = new LinearGradientBrush(rec, this.ForeColor, this.BackColor, LinearGradientMode.Vertical);
            e.Graphics.FillRectangle(brush, 2, 2, rec.Width, rec.Height);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

progressBar.ForeColor = Color.FromArgb(255, 0, 0);
progressBar.BackColor = Color.FromArgb(150, 0, 0);
Run Code Online (Sandbox Code Playgroud)

结果

你可以使用任何你喜欢的渐变!

下载

https://skydrive.live.com/?cid=0EDE5D21BDC5F270&id=EDE5D21BDC5F270%21160&sc=documents#

  • 我意识到这已经老了; 我意识到这是一个尼特(因为最低几乎总是零); 但宽度比例因子应为**(((双倍)值 - (双倍)最小值)/((双倍)最大值 - (双倍)最小值))**以保持正确的方式.:) (2认同)

Mat*_*ine 14

修改了dustyburwell的答案.(我没有足够的代表来自己编辑它.)像他的回答一样,它可以启用"视觉样式".您可以在任何形式的设计视图中设置进度条的ForeColor属性.

using System;
using System.Windows.Forms;
using System.Drawing;

public class ProgressBarEx : ProgressBar
{
    private SolidBrush brush = null;

    public ProgressBarEx()
    {
        this.SetStyle(ControlStyles.UserPaint, true);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        if (brush == null || brush.Color != this.ForeColor)
            brush = new SolidBrush(this.ForeColor);

        Rectangle rec = new Rectangle(0, 0, this.Width, this.Height);
        if (ProgressBarRenderer.IsSupported)
            ProgressBarRenderer.DrawHorizontalBar(e.Graphics, rec);
        rec.Width = (int)(rec.Width * ((double)Value / Maximum)) - 4;
        rec.Height = rec.Height - 4;
        e.Graphics.FillRectangle(brush, 2, 2, rec.Width, rec.Height);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我已经找到了如何解决闪烁问题:在用户定义的ProgressBar的ControlStyles中添加双缓冲,如下所示:SetStyle(ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer,...). (4认同)

小智 5

我把它放到静态类中.

  const int WM_USER = 0x400;
  const int PBM_SETSTATE = WM_USER + 16;
  const int PBM_GETSTATE = WM_USER + 17;

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

  public enum ProgressBarStateEnum : int
  {
   Normal = 1,
   Error = 2,
   Paused = 3,
  }

  public static ProgressBarStateEnum GetState(this ProgressBar pBar)
  {
   return (ProgressBarStateEnum)(int)SendMessage(pBar.Handle, PBM_GETSTATE, IntPtr.Zero, IntPtr.Zero);
  }

  public static void SetState(this ProgressBar pBar, ProgressBarStateEnum state)
  {
   SendMessage(pBar.Handle, PBM_SETSTATE, (IntPtr)state, IntPtr.Zero);
  } 
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你,