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

时间:2009-04-22 19:02:21

标签: c# .net winforms .net-3.5

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

  1. 将绿色更改为红色。
  2. 移除块并将其制成一种颜色。
  3. 关于我想知道如何完成的这两件事的任何信息将会非常有用!

    感谢。

21 个答案:

答案 0 :(得分:103)

好的,我花了一段时间阅读所有的答案和链接。这就是我从他们身上得到的东西:

示例结果

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

enter image description here

使用以下方法,您可以改为:

enter image description here

如何

首先,如果您没有: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);
    }
}

现在,要使用它,只需致电:

ModifyProgressBarColor.SetState(progressBar1, 2);

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

希望它有所帮助!

答案 1 :(得分:70)

由于之前的答案似乎不适用于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);
    }
}

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

答案 2 :(得分:32)

这是最常被接受的代码的无闪烁版本,您可以找到这个问题的答案。所有归功于那些顽固答案的海报。谢谢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();
            }
        }
    }
}

答案 3 :(得分:27)

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

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

pgs.ForeColor = Color.Red;

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

pgs.Style = System.Windows.Forms.ProgressBarStyle.Continuous;

其他修改:您还需要从Application.EnableVisualStyles()(或类似名称)中删除标有Program.cs的行。如果你不能这样做,因为你希望应用程序的其余部分具有视觉样式,那么我建议你自己绘制控件或继续使用WPF,因为这样的事情很容易用WPF。您可以找到所有者绘制进度条on codeplex

的教程

答案 4 :(得分: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);
        }
    }
}

用法:

progressBar.ForeColor = Color.FromArgb(255, 0, 0);
progressBar.BackColor = Color.FromArgb(150, 0, 0);

结果

You can use any gradient you like!

下载

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

答案 5 :(得分: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);
    }
}

答案 6 :(得分: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);
  } 

希望它有所帮助,

马克

答案 7 :(得分:3)

通常,进度条是主题或尊重用户的颜色首选项。因此,要更改颜色,您需要关闭视觉样式并设置ForeColor或自己绘制控件。

对于连续样式而不是块,您可以设置Style属性:

pBar.Style = ProgressBarStyle.Continuous;

答案 8 :(得分:2)

修改

通过你正在使用XP主题的东西的声音,它具有基于绿色块的prog-bar。尝试将您的UI样式翻转到Windows Classic并再次测试,但您可能需要实现自己的OnPaint事件,以使其在所有UI样式中执行您想要的操作

或者正如其他人指出的那样,为您的应用程序禁用VisualStyles。

<强>原始

据我所知,进度条的渲染与你选择的windows主题风格一致(win2K,xp,vista)

您可以通过设置属性

来更改颜色
ProgressBar.ForeColor

我不确定你能做多少但是......

进行一些谷歌搜索

这是MS KB创建“平滑”进度条的文章

http://support.microsoft.com/kb/323116

答案 9 :(得分:2)

更改# Inside your-rails-app/ directory: # 1. Remove config/application.rb rm config/application.rb # 2. Move up one directory cd .. # 3. Regenerate rails application with the --skip # option, using the name of your-rails-app. The # --skip option will not generate files that # already exist. # # This assumes you have rails installed as a global # gem, of the version given in the command (version # x.y.z in this case, replace with the version of Rails # your app uses, e.g. 4.2.88): rails _x.y.z_ new your-rails-app --skip --skip-test-unit # 4. Run git status to see if any files were unexpectedly added # (for example the README.rdoc file will be created # if it did not exist). git status # 5. Clean up and commit the changes you want. Color(即时更改)

Value放在最上面......

使用using System.Runtime.InteropServices;

进行通话

我注意到如果你更改了条的值(它有多大),那么如果它的颜色不是默认的绿色,它就不会改变。 我使用了user1032613的代码并添加了一个Value选项。

ColorBar.SetState(progressBar1, ColorBar.Color.Yellow, myValue);

答案 10 :(得分:2)

所有这些方法都不适合我,但这种方法允许您将其更改为颜色字符串。

请注意,我在StackOverflow上的其他位置找到了此代码并稍微更改了一下。我已经忘记了我在哪里找到了这段代码而我无法将它链接起来因为那样对不起。

但无论如何,我希望这段代码可以帮助我真正帮助过我的人。

private void ProgressBar_MouseDown(object sender, MouseButtonEventArgs e)
    {
        var converter = new System.Windows.Media.BrushConverter();
        var brush = (Brush)converter.ConvertFromString("#FFB6D301");
        ProgressBar.Foreground = brush;
    }

使用名称“ProgressBar”替换为您自己的进度条名称。您也可以使用其他参数触发此事件,只需确保其内部括号。

答案 11 :(得分:2)

我建议您再看一下CodeProject上的这篇文章:Progress-O-Doom。太棒了!

答案 12 :(得分:2)

尝试使用messsage PBM_SETBARCOLOR,这应该可以解决SendMessage的问题

有关示例,请参阅http://www.vbforums.com/showthread.php?t=248721

答案 13 :(得分:1)

以防任何人寻找其他选项....你可以扩展一个面板,使用它作为背景(白色或其他),在其中添加另一个面板作为前景(移动栏)。然后你可以完全控制颜色等等。

答案 14 :(得分:1)

只需在Visual Basic Solution Explorer(您的vb文件所在位置)中右键单击您的项目,然后从菜单中选择属性。在弹出的窗口中取消选择“启用XP视觉样式”,现在当你设置forecolor时,它现在应该可以正常工作。

答案 15 :(得分:0)

以下:引用: 通常,进度条是主题或尊重用户的颜色首选项。因此,要更改颜色,您需要关闭视觉样式并设置ForeColor或自己绘制控件。

对于连续样式而不是块,您可以设置Style属性:

pBar.Style = ProgressBarStyle.Continuous;

ProgressBarStyle.Continuous与Blocks对启用VistualStyles无用......

Block仅适用于已禁用的视觉样式... 这使得所有这一切都成为一个有争议的问题(关于自定义进度颜色) 禁用vistual样式...进度条应根据前景色进行着色。

我使用了威廉丹尼尔的答案组合(启用了视觉样式,因此ForeColor不仅仅是扁平的,没有风格) 和 Barry的答案(进度条上的自定义文字)来自:How do I put text on ProgressBar?

答案 16 :(得分:0)

垂直条向下以红色显示:

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



public class VerticalProgressBar : ProgressBar
{


    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.Style |= 0x04;
            return cp;

        }
    }
    private SolidBrush brush = null;

    public VerticalProgressBar()
    {
        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.DrawVerticalBar(e.Graphics, rec);
        rec.Height = (int)(rec.Height * ((double)Value / Maximum)) - 4;
        rec.Width = rec.Width - 4;
        e.Graphics.FillRectangle(brush, 2, 2, rec.Width, rec.Height);

    } 
}

答案 17 :(得分:0)

尊重WXP视觉样式答案的VB.Net彩色进度条是......

我从3月17日的'user1032613'开始回答。请注意,这现在是一个模块,而不是一个类。从那里我转换了代码,但需要更多。特别是转换后的代码显示了一个DirectCast函数,用于将“状态”整数转换为无法工作的IntPtr类型。

Imports System.Runtime.InteropServices

Public Module ModifyProgressBarColor

    Private Declare Function SendMessage Lib "User32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Long) As Long

    <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=False)> _
    Private Function SendMessage(hWnd As IntPtr, Msg As UInteger, w As IntPtr, l As IntPtr) As IntPtr
    End Function

    <System.Runtime.CompilerServices.Extension()> _
    Public Sub SetState(pBar As ProgressBar, state As Integer)

        '-- Convert state as integer to type IntPtr
        Dim s As IntPtr
        Dim y As Integer = state
        s = IntPtr.op_Explicit(y)

        '-- Modify bar color
        SendMessage(pBar.Handle, 1040, s, IntPtr.Zero)

    End Sub

End Module

再次使用此行在使用代码中调用它:

Call ModifyProgressBarColor.SetState(prb, 2)

BTW - 我尝试了其他颜色 - 0,4,5 - 它们都显示为绿色。

答案 18 :(得分:0)

我发现可以通过在进度条内部绘制一个矩形并根据进度的当前值设置其宽度来完成此操作。 我还添加了从右到左进度的支持。 这样,您就无需使用Image,而且由于Rectnalge.Inflate不会被调用,因此绘制的矩形会更小。

plt.savefig('mypath/myfile.pgf', bbox_inches='tight', format='svg')

答案 19 :(得分:0)

我认为,所有解决方案中最简单的解决方案只是一个快速解决方案,但是您可以从Program.cs中删除Application.EnableVisualStyles()并对其添加注释,也可以为包含Main函数的部分命名。之后,您可以通过progressBar.ForeColor = Color.TheColorYouDesire;

从进度条自由更改颜色。

static void Main()
        {
            //Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
         }

答案 20 :(得分:-5)

编辑:在两分钟内我开始点击vs并检查语法我被击败了它有更好的回应。我喜欢这个网站。

        progressBar1 = new ProgressBar();
        progressBar1.ForeColor = Color.Red;