プログレスバーで2つのことを行いたいのですが。
- 緑色を赤色に変更します。
- ブロックを外して単色にします。
達成する方法について私が疑問に思うこれら2つのことについての情報は、非常に理解されます!
ありがとう。
プログレスバーで2つのことを行いたいのですが。
達成する方法について私が疑問に思うこれら2つのことについての情報は、非常に理解されます!
ありがとう。
回答:
以前の回答は、ビジュアルスタイルでは機能しないようです。おそらく、独自のクラスを作成するか、進行状況バーを拡張する必要があります。
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;
次に、この新しいクラスを作成するか、コードを既存の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);
}
}
これを使用するには、次のように呼び出します。
progressBar1.SetState(2);
SetStateの2番目のパラメータ、1 =通常(緑)に注意してください。2 =エラー(赤); 3 =警告(黄色)。
それが役に立てば幸い!
public const uint PBM_SETSTATE = 0x0410; // 1040
これは、この質問に対する回答として見つけることができる最も受け入れられているコードのちらつきのないバージョンです。それらの致命的な答えのポスターへのすべての信用。ダスティ、クリス、マット、ジョシュに感謝!
コメントの1つにある「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);
}
}
}
}
デザイナーでは、ForeColorプロパティを任意の色に設定するだけです。赤の場合、事前定義された色があります。
コード(C#)でこれを行うには、次のようにします。
pgs.ForeColor = Color.Red;
編集:ええ、スタイルも連続に設定します。コードでは、このように:
pgs.Style = System.Windows.Forms.ProgressBarStyle.Continuous;
別の編集:(または類似のもの)Application.EnableVisualStyles()
から読み取る行も削除する必要がありますProgram.cs
。アプリケーションの残りの部分に視覚的なスタイルを持たせたいためにこれを実行できない場合は、コントロールを自分でペイントするか、WPFに進むことをお勧めします。所有者がcodeplexにプログレスバーを描画するチュートリアルを見つけることができます
Matt BlaineとChris Persichettiの回答を使用して、無限に色を選択できるようにしながら、少し見栄えの良いプログレスバーを作成しました(基本的にはMattのソリューションの1行を変更しました)。
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#
LinearGradientBrush
、recの幅を0として読み取るため、このコードは値4 に達するとエラーになります。最も簡単な修正は、コードで4pxの「パディング」を行わず、代わりに配置することですパネルやパディングで何か(あなたが国境をしたい場合)となっrec.Width = (int)((rec.Width * scaleFactor) - 4)
にrec.Width = (int)(rec.Width * scaleFactor) + 1
ダスティバーウェルの答えの修正。(私は自分で編集するのに十分な担当者がいません。)彼の答えのように、「ビジュアルスタイル」を有効にして動作します。プログレスバーの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);
}
}
これを静的クラスに入れるだけです。
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);
}
それが役に立てば幸い、
マーク
編集
物音によって、緑のブロックベースのプログラムバーがあるXPテーマを使用しています。UIスタイルをWindowsクラシックに切り替えてもう一度テストしてください。ただし、すべてのUIスタイルで必要なことを実行するには、独自のOnPaintイベントを実装する必要がある場合があります。
または、他の誰かが指摘したように、アプリケーションのVisualStylesを無効にします。
元の
私の知る限りでは、プログレスバーのレンダリングは、選択したWindowsテーマスタイル(win2K、xp、vista)とインラインで行われます。
プロパティを設定して色を変更できます
ProgressBar.ForeColor
しかし、あなたがもっともっとできるかどうかはわかりません...
いくつかグーグルを行います
「スムーズ」プログレスバーの作成に関するMS KBの記事があります。
メッセージPBM_SETBARCOLORを使用してみてください、それはSendMessageでトリックを行うはずです
例については、http://www.vbforums.com/showthread.php?t = 248721を参照してください。
これらの方法はすべて私にとってはうまくいきませんが、この方法を使用すると、色の文字列に変更できます。
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」という名前が使用されている場合は、独自のプログレスバー名に置き換えてください。他の引数を使用してこのイベントをトリガーすることもできます。その場合は、その内側の角かっこがどこかにあることを確認してください。
変化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
}
}
pBar.Value = pBar.Maximum;
し、SendMessage(pBar.Handle, 1040, (IntPtr)(int)Color.Green, IntPtr.Zero);
正しい新しい色を表示するプログレスのための条件-体の内部。
注:引用:通常、進行状況バーはテーマが設定されているか、ユーザーの色設定を反映しています。したがって、色を変更するには、視覚スタイルをオフにして設定する必要がありますForeColor
、コントロールを自分でまたは描画するます。
ブロックの代わりに連続スタイルについては、Style
プロパティを設定できます:
pBar.Style = ProgressBarStyle.Continuous;
ProgressBarStyle.ContinuousとBlocksは、VistualStylesが有効になっていると役に立ちません...
ブロックは、視覚スタイルが無効になっている場合にのみ機能します...これにより、(カスタムプログレスカラーに関して)このすべての問題点がレンダリングされます。
ウィリアムダニエルの回答(視覚スタイルが有効になっているため、スタイルがなくてもForeColorがフラットになるだけではありません)とバリーの回答(プログレスバーのカスタムテキストへ)を組み合わせて使用しました。
垂直バーUPダウン用赤色:
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色のプログレスバーは...
3/17/12の「user1032613」からの回答から始めました。これはモジュールではなく、クラスになっていることに注意してください。そこからコードを変換しましたが、さらに必要でした。特に、変換されたコードは、「状態」整数を機能しないIntPtr型に変換するDirectCast関数を示しました。
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-それらはすべて緑色で表示されました。
私は今答えられるにはあまりにも古いその方法を知っている..しかし、まだ、@に小さな微調整ダニエル・ゼロ値プログレスバーが表示されないという問題を整流するための答え。内側の長方形の幅がゼロ以外であることが判明した場合にのみ、プログレスを描画してください。
すべての貢献者に感謝します。
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();
}
}
}
}
}
これは、進行状況バーの内側に長方形を描画し、進行状況の現在の値に応じて幅を設定することで実行できることがわかりました。右から左への進行のサポートも追加しました。この方法では、Imageを使用する必要はありません。Rectnalge.Inflateは呼び出されないため、描画される四角形は小さくなります。
public partial class CFProgressBar : ProgressBar
{
public CFProgressBar()
{
InitializeComponent();
this.SetStyle(ControlStyles.UserPaint, true);
}
protected override void OnPaintBackground(PaintEventArgs pevent) { }
protected override void OnPaint(PaintEventArgs e)
{
double scaleFactor = (((double)Value - (double)Minimum) / ((double)Maximum - (double)Minimum));
int currentWidth = (int)((double)Width * scaleFactor);
Rectangle rect;
if (this.RightToLeftLayout)
{
int currentX = Width - currentWidth;
rect = new Rectangle(currentX, 0, this.Width, this.Height);
}
else
rect = new Rectangle(0, 0, currentWidth, this.Height);
if (rect.Width != 0)
{
SolidBrush sBrush = new SolidBrush(ForeColor);
e.Graphics.FillRectangle(sBrush, rect);
}
}
}
私はすべての最も簡単な解決策だと思います、それはただの簡単な修正ですが、Program.csからApplication.EnableVisualStyles()を削除するかコメントを付けることができますが、Main関数を含む部分に名前を付けることができます。その後、progressBar.ForeColor = Color.TheColorYouDesire;を使用して、プログレスバーの色を自由に変更できます。
static void Main()
{
//Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
編集:2つのミニッツで、vsを起動し、構文を確認して、はるかに優れた応答でそれに負けました。私はこのサイトが大好きです。
progressBar1 = new ProgressBar();
progressBar1.ForeColor = Color.Red;