如何在C#.NET 3.5中更改进度条的颜色?
我想在我的进度条上做两件事情。
- 将绿色改为红色。
- 删除块,并在一个颜色。
任何有关这两件事我不知道如何完成的信息将非常appreaciated!
谢谢。
由于以前的答案似乎不适用于视觉样式。 您可能需要创build自己的课程或扩展进度栏:
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); } }
编辑:更新的代码,使进度栏使用视觉样式的背景
好吧,我花了一段时间阅读所有的答案和链接。 以下是我从他们那里得到的东西:
样品结果
接受的答案禁用视觉样式,它允许您将颜色设置为任何您想要的,但结果看起来很简单:
使用下面的方法,你可以得到这样的东西:
如何
首先,包含这个如果你还没有using System.Runtime.InteropServices;
其次,您可以创build这个新的类,或者将其代码放入一个现有的static
非generics类:
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 =警告(黄色)。
希望能帮助到你!
这是您可以find的最为接受的代码的无闪烁版本,作为此问题的答案。 所有信贷的肥胖的答案的海报。 谢谢Dusty,Chris,Matt和Josh!
就像“Fueled”在其中一个评论中的要求一样,我还需要一个performance得更加专业化的版本。 这段代码像前面的代码一样维护样式,但添加了一个离屏图像渲染和graphics缓冲(并正确地configurationgraphics对象)。
结果:所有的好,没有闪烁。 🙂
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(); } } } }
在devise器中,只需将ForeColor属性设置为任何你想要的颜色即可。 在红色的情况下,它有一个预定义的颜色。
要在代码(C#)中做到这一点:
pgs.ForeColor = Color.Red;
编辑 :噢,也设置风格连续。 在代码中,像这样:
pgs.Style = System.Windows.Forms.ProgressBarStyle.Continuous;
另一个编辑:您还需要从Program.cs
(或类似的)中删除读取Application.EnableVisualStyles()
的行。 如果你不能这样做,因为你希望应用程序的其余部分有视觉样式,那么我build议你自己绘制控件,或者转向WPF,因为WPF很容易实现。 你可以find一个关于所有者在codeplex上绘制进度条的教程
修改dustyburwell的答案。 (我自己没有足够的代表来编辑它。)就像他的回答,它启用了“视觉样式”。 您可以在任何forms的devise视图中设置进度条的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); } }
使用马特·布莱恩和克里斯·佩尔西切蒂的回答,我创build了一个进度条,看起来更漂亮,同时允许无限的颜色select(基本上我改变了马特解决scheme中的一行):
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);
结果
下载
https://skydrive.live.com/?cid=0EDE5D21BDC5F270&id=EDE5D21BDC5F270%21160&sc=documents#
我只是把它放到一个静态类中。
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); }
希望能帮助到你,
渣子
通常进度条不是主题就是用户的颜色偏好。 所以要改变颜色,你需要closures视觉样式并设置ForeColor
或者自己绘制控件。
至于连续的样式而不是块,你可以设置Style
属性:
pBar.Style = ProgressBarStyle.Continuous;
编辑
通过你使用XP主题的东西的声音,它具有绿色块基于编程栏。 尝试翻转你的UI风格到Windows经典再次testing,但你可能需要实现自己的OnPaint事件,让它做你想做的所有UI样式
或者像别人指出的那样,为你的应用程序禁用VisualStyles。
原版的
据我所知,进度条的渲染与您select的Windows主题风格(win2K,xp,vista)
您可以通过设置属性来更改颜色
ProgressBar.ForeColor
我不确定你可以做更多的事情,但是…
做一些Googlesearch
这里有一篇来自MS KB的关于创build“平滑”进度条的文章
我build议你也看看这篇关于CodeProject: Progress-O-Doom的文章 。 这很棒!
以防万一任何人寻找另一个选项….你可以扩展一个面板,使用它作为背景(白色或其他),添加另一个面板里面的前景(移动栏)。 然后你有完全的控制改变颜色等
只需右键单击Visual Basic解决scheme资源pipe理器(您的vb文件所在的位置)中的项目,然后从菜单中select属性。 在popup的窗口中取消select“启用XP视觉样式”,现在当您设置forecolor时,它现在应该工作。
尝试使用messsage PBM_SETBARCOLOR,这应该与SendMessage做的伎俩
所有这些方法都无法为我工作,但是这种方法允许您将其更改为颜色string。
请注意,我从StackOverflow的其他地方find了这个代码,并对其进行了一些修改。 我已经忘了我在哪里find这个代码,我不能链接它,因为那个很抱歉。
但无论如何,我希望这个代码可以帮助真正帮助我的人。
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”replace您自己的进度条名称。 你也可以用其他参数触发这个事件,只要确保它的内部括号。
更改Color
和Value
(即时更改)
把using System.Runtime.InteropServices;
顶部…
调用ColorBar.SetState(progressBar1, ColorBar.Color.Yellow, myValue);
我注意到,如果你改变了栏的值(它有多大),那么它将不会改变,如果它是在默认的绿色以外的颜色。 我拿了user1032613的代码并添加了一个Value选项。
public static class ColorBar { [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)] static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr w, IntPtr l); public enum Color { None, Green, Red, Yellow } public static void SetState(this ProgressBar pBar, Color newColor, int newValue) { if (pBar.Value == pBar.Minimum) // If it has not been painted yet, paint the whole thing using defualt color... { // Max move is instant and this keeps the initial move from going out slowly pBar.Value = pBar.Maximum; // in wrong color on first painting SendMessage(pBar.Handle, 1040, (IntPtr)(int)Color.Green, IntPtr.Zero); } pBar.Value = newValue; SendMessage(pBar.Handle, 1040, (IntPtr)(int)Color.Green, IntPtr.Zero); // run it out to the correct spot in default SendMessage(pBar.Handle, 1040, (IntPtr)(int)newColor, IntPtr.Zero); // now turn it the correct color } }
自定义:Quote:通常进度条是主题或尊重用户的颜色偏好。 所以要改变颜色,你需要closures视觉样式并设置ForeColor
或者自己绘制控件。
至于连续的样式而不是块,你可以设置Style
属性:
pBar.Style = ProgressBarStyle.Continuous;
ProgressBarStyle.Continuous与块是无用的VistualStyles启用…
块(S)将只适用于禁用视觉样式…这使所有这一切都成为一个争议点(关于自定义进度颜色)禁用视觉样式…进度条应根据前景色进行着色。
我使用了William Daniel的答案(启用了视觉样式,因此ForeColor不会只是没有样式的平面)和Barry的答案(对进度条上的自定义文本): 如何在ProgressBar上放置文本?
垂直酒吧上升下来在红色:
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); } }
尊重WXP视觉样式的VB.Net彩色进度条是…
我从2012年3月17日的“user1032613”开始回答。 请注意,这现在是一个模块,而不是一个类。 从那里我转换了代码,但更多是需要的。 特别是转换后的代码显示了一个DirectCast函数,用于将“状态”整数转换为无效的IntPtrtypes。
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)
顺便说一句 – 我尝试了其他颜色 – 0,4,5 – 他们都显示绿色。
我知道它的方式太老了,现在不能回答。但是,对丹尼尔的回答来说,一个小小的调整来解决不显示零值进度条的问题。 只有在发现内部矩形的宽度不为零的情况下才绘制Progress。
感谢所有的贡献者。
public class ProgressBarEx : ProgressBar { public ProgressBarEx() { 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) { LinearGradientBrush brush = new LinearGradientBrush(rect, this.ForeColor, this.BackColor, LinearGradientMode.Vertical); offscreen.FillRectangle(brush, inset, inset, rect.Width, rect.Height); e.Graphics.DrawImage(offscreenImage, 0, 0); offscreenImage.Dispose(); } } } } }
编辑:在这两个minuites它花了我开火vs和检查我被殴打的语法有更好的答复。 我喜欢这个网站。
progressBar1 = new ProgressBar(); progressBar1.ForeColor = Color.Red;