Saya ingin melakukan dua hal di bilah kemajuan saya.
- Ubah warna hijau menjadi merah.
- Hapus blok dan buat dalam satu warna.
Setiap informasi tentang dua hal yang saya ingin tahu bagaimana mencapainya akan sangat dihargai!
Terima kasih.
Karena jawaban sebelumnya tampaknya tidak berfungsi dengan Gaya Visual. Anda mungkin perlu membuat kelas Anda sendiri atau memperluas bilah kemajuan:
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);
}
}
EDIT: Kode yang diperbarui untuk membuat bilah kemajuan menggunakan gaya visual untuk latar belakang
Oke, saya butuh beberapa saat untuk membaca semua jawaban dan tautan. Inilah yang saya dapatkan dari mereka:
Hasil Sampel
Jawaban yang diterima menonaktifkan gaya visual, itu memungkinkan Anda untuk mengatur warna ke apapun yang Anda inginkan, tetapi hasilnya terlihat biasa:
Dengan menggunakan metode berikut, Anda bisa mendapatkan sesuatu seperti ini:
Bagaimana caranya
Pertama, sertakan ini jika Anda belum:
using System.Runtime.InteropServices;
Kedua, Anda dapat membuat kelas baru ini, atau memasukkan kodenya ke dalam
static
kelas non-generik yang sudah ada :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); } }
Sekarang, untuk menggunakannya, cukup panggil:
progressBar1.SetState(2);
Perhatikan parameter kedua di SetState, 1 = normal (hijau); 2 = kesalahan (merah); 3 = peringatan (kuning).
Semoga membantu!
sumber
public const uint PBM_SETSTATE = 0x0410; // 1040
Ini adalah versi bebas-flicker dari kode yang paling diterima yang dapat Anda temukan sebagai jawaban atas pertanyaan ini. Semua penghargaan untuk poster jawaban fatastic itu. Terima kasih Dusty, Chris, Matt, dan Josh!
Seperti permintaan "Fueled" di salah satu komentar, saya juga membutuhkan versi yang berperilaku sedikit lebih ... profesional. Kode ini mempertahankan gaya seperti pada kode sebelumnya, tetapi menambahkan render gambar di luar layar dan buffering grafik (dan membuang objek grafik dengan benar).
Hasilnya: semua bagus, dan tidak ada flicker. :)
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); } } } }
sumber
Di desainer, Anda hanya perlu menyetel properti ForeColor ke warna apa pun yang Anda inginkan. Dalam kasus Merah, ada warna yang telah ditentukan sebelumnya.
Untuk melakukannya dalam kode (C #) lakukan ini:
Edit : Oh ya, juga atur Style ke kontinu. Dalam kode, seperti ini:
Edit Lain: Anda juga harus menghapus baris yang terbaca
Application.EnableVisualStyles()
dari AndaProgram.cs
(atau serupa). Jika Anda tidak dapat melakukan ini karena Anda ingin aplikasi lainnya memiliki gaya visual, saya sarankan untuk mengecat sendiri kontrolnya atau beralih ke WPF karena hal semacam ini mudah dilakukan dengan WPF. Anda dapat menemukan tutorial tentang pemilik yang menggambar bilah kemajuan di codeplexsumber
Menggunakan jawaban Matt Blaine dan Chris Persichetti, saya telah membuat bilah kemajuan yang terlihat sedikit lebih bagus sambil memungkinkan pilihan warna tak terbatas (pada dasarnya saya mengubah satu baris dalam solusi 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); } } }
Pemakaian:
progressBar.ForeColor = Color.FromArgb(255, 0, 0); progressBar.BackColor = Color.FromArgb(150, 0, 0);
Hasil
Unduh
https://skydrive.live.com/?cid=0EDE5D21BDC5F270&id=EDE5D21BDC5F270%21160&sc=documents#
sumber
LinearGradientBrush
membaca lebar rekam sebagai 0. Perbaikan termudah adalah dengan tidak melakukan "pengisi" 4px dalam kode dan sebagai gantinya menempatkannya di panel atau sesuatu dengan bantalan (jika Anda ingin perbatasan) dan membuatrec.Width = (int)((rec.Width * scaleFactor) - 4)
menjadirec.Width = (int)(rec.Width * scaleFactor) + 1
Modifikasi jawaban dustyburwell. (Saya tidak memiliki cukup perwakilan untuk mengeditnya sendiri.) Seperti jawabannya, ini berfungsi dengan "Gaya Visual" diaktifkan. Anda bisa menyetel properti ForeColor bilah kemajuan dalam tampilan desain bentuk apa pun.
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); } }
sumber
Saya hanya memasukkan ini ke dalam kelas statis.
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); }
Semoga membantu,
Marc
sumber
Biasanya bilah kemajuan bertema atau menghormati preferensi warna pengguna. Jadi untuk mengubah warna Anda perlu mematikan gaya visual dan mengaturnya
ForeColor
atau menggambar kontrol sendiri.Sedangkan untuk gaya berkelanjutan sebagai ganti blok Anda dapat mengatur
Style
properti:sumber
EDIT
Dengan suara hal-hal yang Anda gunakan Tema XP yang memiliki prog-bar berbasis blok hijau. Coba balikkan Gaya UI Anda ke Windows Classic dan uji lagi, tetapi Anda mungkin perlu mengimplementasikan acara OnPaint Anda sendiri untuk membuatnya melakukan apa yang Anda inginkan di semua Gaya UI
Atau seperti yang ditunjukkan orang lain, nonaktifkan VisualStyles untuk aplikasi Anda.
Asli
Sejauh yang saya tahu, rendering bilah Kemajuan terjadi sesuai dengan gaya tema windows yang Anda pilih (win2K, xp, vista)
Anda dapat mengubah warna dengan mengatur properti
Saya tidak yakin Anda dapat melakukan lebih banyak lagi namun ...
melakukan googling
Ada artikel di sini dari MS KB tentang membuat bilah kemajuan "Mulus"
http://support.microsoft.com/kb/323116
sumber
coba gunakan pesan PBM_SETBARCOLOR, yang seharusnya melakukan trik dengan SendMessage
Lihat http://www.vbforums.com/showthread.php?t=248721 sebagai contoh.
sumber
Semua metode ini gagal berfungsi untuk saya, tetapi metode ini memungkinkan Anda mengubahnya menjadi string warna.
Harap dicatat bahwa saya menemukan kode ini dari tempat lain di StackOverflow dan mengubahnya sedikit. Sejak saat itu saya lupa di mana saya menemukan kode ini dan saya tidak dapat menautkannya karena itu jadi maaf untuk itu.
Tapi bagaimanapun saya berharap kode ini membantu seseorang itu benar-benar membantu saya.
private void ProgressBar_MouseDown(object sender, MouseButtonEventArgs e) { var converter = new System.Windows.Media.BrushConverter(); var brush = (Brush)converter.ConvertFromString("#FFB6D301"); ProgressBar.Foreground = brush; }
Di mana nama "ProgressBar" digunakan, ganti dengan nama bilah kemajuan Anda sendiri. Anda juga dapat memicu peristiwa ini dengan argumen lain, cukup pastikan tanda kurung dalamnya di suatu tempat.
sumber
Ubah
Color
danValue
(perubahan instan)Letakkan
using System.Runtime.InteropServices;
di atas ...Telepon dengan
ColorBar.SetState(progressBar1, ColorBar.Color.Yellow, myValue);
Saya perhatikan bahwa jika Anda mengubah nilai bilah (seberapa besar) maka itu tidak akan berubah jika dalam warna selain hijau default. Saya mengambil kode user1032613 dan menambahkan opsi Nilai.
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 } }
sumber
pBar.Value = pBar.Maximum;
danSendMessage(pBar.Handle, 1040, (IntPtr)(int)Color.Green, IntPtr.Zero);
masuk ke dalam kondisi-tubuh untuk menunjukkan warna baru yang benar.Untuk berjaga-jaga jika ada yang mencari opsi lain .... Anda dapat memperluas Panel, menggunakannya sebagai latar belakang (putih atau apa pun), tambahkan Panel lain di dalamnya untuk latar depan (bilah bergerak). Kemudian Anda memiliki kontrol total untuk mengubah warna, dll.
sumber
Cukup klik kanan pada proyek Anda di Visual Basic Solution Explorer (tempat file vb Anda) dan pilih properti dari menu. Pada jendela yang muncul hapus pilihan "Aktifkan XP Visual Styles" dan sekarang ketika Anda mengatur warna depan, itu harus bekerja sekarang.
sumber
Јοеу: Quote: Biasanya progress bar baik bertema atau menghormati preferensi warna pengguna. Jadi untuk mengubah warna Anda perlu mematikan gaya visual dan mengatur
ForeColor
atau menggambar kontrol sendiri.Sedangkan untuk gaya berkelanjutan sebagai ganti blok Anda dapat mengatur
Style
properti:ProgressBarStyle.Continuous versus Blocks tidak berguna dengan VistualStyles diaktifkan ...
Blok (s) hanya akan bekerja dengan gaya visual dinonaktifkan ... yang menjadikan semua ini titik diperdebatkan (berkaitan dengan warna kemajuan kustom) Dengan gaya visual dinonaktifkan ... bilah kemajuan harus diwarnai berdasarkan warna depan.
Saya menggunakan kombinasi jawaban William Daniel (dengan gaya visual yang diaktifkan, sehingga Warna Depan tidak hanya akan datar tanpa gaya) dan jawaban Barry (untuk teks kustom di bilah kemajuan) dari: Bagaimana cara meletakkan teks di ProgressBar?
sumber
Vertical Bar UP Untuk Down dengan warna merah:
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); } }
sumber
Bilah kemajuan berwarna VB.Net yang mengikuti jawaban Gaya Visual WXP adalah ...
Saya mulai dengan jawaban dari 'user1032613' pada 3/17/12. Perhatikan bahwa ini sekarang menjadi Module, bukan kelas. Dari sana saya mengubah kode tetapi lebih banyak yang dibutuhkan. Secara khusus kode yang dikonversi menunjukkan fungsi DirectCast untuk mengubah integer 'state' menjadi jenis IntPtr yang tidak berfungsi.
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
Dan sekali lagi panggil ini dalam menggunakan kode dengan baris ini:
Call ModifyProgressBarColor.SetState(prb, 2)
BTW - Saya mencoba warna lain - 0, 4, 5 - semuanya hanya menampilkan warna hijau.
sumber
Saya tahu caranya terlalu tua untuk dijawab sekarang .. tapi tetap saja, sedikit perubahan pada jawaban @ Daniel untuk memperbaiki masalah tidak menunjukkan bilah kemajuan bernilai nol. Gambar saja Progress hanya jika lebar persegi panjang bagian dalam ternyata bukan nol.
Terima kasih untuk semua kontributor.
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(); } } } } }
sumber
Saya menemukan ini dapat dilakukan dengan menggambar persegi panjang di dalam bilah kemajuan, dan untuk mengatur lebarnya sesuai dengan nilai kemajuan saat ini. Saya juga menambahkan dukungan untuk kemajuan dari kanan ke kiri. Dengan cara ini Anda tidak perlu menggunakan Image, dan karena Rectnalge.Inflate tidak disebut persegi panjang yang digambar lebih kecil.
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); } } }
sumber
Saya pikir solusi paling sederhana dari semuanya, itu hanya perbaikan cepat, tetapi Anda dapat menghapus, mengomentari Application.EnableVisualStyles () dari Program.cs, atau bagaimanapun Anda memberi nama bagian Anda yang berisi fungsi Utama. Setelah itu Anda dapat dengan bebas mengubah warna dari bilah kemajuan dengan progressBar.ForeColor = Color.TheColorYouDesire;
static void Main() { //Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); }
sumber
Sunting: dalam dua menit yang saya butuhkan untuk menjalankan vs dan memeriksa sintaks saya dipukuli dengan respons yang jauh lebih baik. saya suka situs ini
progressBar1 = new ProgressBar(); progressBar1.ForeColor = Color.Red;
sumber